6

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?
Jimmy
  • 16,123
  • 39
  • 133
  • 213
  • http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.22.1 – Mat Aug 08 '12 at 10:37
  • Try `'c' & 'd'` which matches ` or 'c' + 'd' which matches Ç and 'c'/'d' matches the nul byte \0 ;) – Peter Lawrey Aug 08 '12 at 10:44
  • @PatrykDobrowolski Sorry didn't remember about bitwise...my (lame) excuse is that its not in the syllabus for SCJP6 ;) – Jimmy Aug 08 '12 at 10:47
  • The compared values are not booleans, so this is not going to be a boolean comparison, but instead a bitwise operation. System.out.println('c' | 'd'); // will output 103 – Eugene Aug 08 '12 at 10:39
  • +1 Which is the letter `g` ;) Try `System.out.println((char) ('c' | 'd'));` – Peter Lawrey Aug 08 '12 at 10:42
  • *Non sequitur.* 1 == 2 is a Boolean expression but the operands aren't. – user207421 Aug 09 '12 at 00:01

4 Answers4

12

'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.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
6

'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();
}
Hiery Nomus
  • 17,429
  • 2
  • 41
  • 37
4
('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.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
1

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

'c' | 'd' is bitwise OR

Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85