Why is a boolean expression valid in a case block, when booleans are not supported data types for switches?

1.4k views Asked by At

After reading some of the SCJP certification last night, I got thinking about switch statements and how the expressions are evaluated, and I'm a little puzzled by something.

Java won't let you switch on a boolean, so the following will not compile :

public static void switchOnBoolean(boolean theBool)
    {
        System.out.println("\n\nAssessing boolean :" + theBool);
        // line below won't compile, since booleans are not valid for the switch statement
        switch(theBool)
        {
            case true:
            {
                System.out.println("The boolean was true");
                break;
            }
            case false:
            {
                System.out.println("The boolean was false");
            }
        }
    }

However, the compiler will not complain if you attempt to use an expression that evaluates to a boolean value in a case block, such as :

public static void switchOnChar(char theChar)
    {
        System.out.println("\n\nAssessing char : " + theChar);
        switch(theChar)
        {
            case 'a':
            {
                System.out.println("The char was a");
                break;
            }
            case 'b':
            {
                System.out.println("The char was b");
                break;
            }
            case ('c' | 'd'):
            {
                System.out.println("The char was c or d");
                break;
            }
            default:
            {
                System.out.println("The char didn't match anything, must be something else");
            }
        }
    }

Ultimately, I can't ever get into the case ('c' | 'd') since it would presumably evaluate to a boolean...

So my question is:

  1. Why is it legal to use something like ('c' | 'd') ?
  2. How could that ever be useful, since that would be unreachable
  3. If you ever wanted to case on more than one value, but without using a default, is your only choice to re-implement as an if-else statement?
4

There are 4 answers

0
Pshemo On BEST ANSWER

'c' | 'd' wont return boolean. In this case | is bitwise OR not boolean OR.

You can see it in this example how it is calculated

System.out.println(Integer.toBinaryString('c'));
System.out.println(Integer.toBinaryString('d'));
System.out.println("=======");
System.out.println(Integer.toBinaryString('c' | 'd'));

Output

1100011
1100100
=======
1100111

and binary 1100111 is equal to 103 decimal integer so it is valid case argument.

1
Adam Arold On
('c' | 'd')

is bitwise or so it won't return a boolean value, it is completely valid.

If you try that out like this:

System.out.println('c' | 'd');

it will print out 103 which is the ASCII code for g.

0
Nandkumar Tekale On

If you do 'c' || 'd' then you will get expected boolean error and won't compile.

'c' | 'd' is bitwise OR

0
Hiery Nomus On

'c' | 'd' is a bitwise or which results in 'g', so valid in the switch.

You can match more than one case without going to the if-statement like

switch(theChar) {
    case 'a':
        break;
    case 'b':
        break;
    case 'c':
    case 'd':
        System.out.println("c or d");
        break;
    default:
        throw new IllegalStateException();
}