Thursday, January 05, 2006

switch labels and constant expressions

Thomas writes that he is confused why this code won't compile when it satisfies the switch label requirements in the JLS specification. This snippet is cut from his site.

1. public class Harbour {
2. static void foo(){}
3. public static void main(String[] args) {
4. int bootNumber = new Integer(2007);
5. final Integer year = 2007;
6. switch (bootNumber) {
7. case 10: foo();break; // compiles, as expected
8. case Integer.MIN_VALUE: foo() ;break; // compiles, as expected
9. case year: foo();break; // does not compile
10. case year.intValue(): foo() ;break; // does not compile
11. }
12. }
13. }

Examining line 10, we see that year.intValue() is the label & since this is not a constant expression, the compile fails.

Looking at line 9, year is the label. This seems okay at a glance, but since year "would be" converted to year.intValue() at runtime, it is not a constant expression.

Note that if BOTH of these did compile somehow, it would still fail to compile because you have duplicate case labels. (year & year.intValue() would essentially return the same thing)

Now it's pretty easy to convince yourself that year.intValue() is a constant since it's final, but it's not a "constant expression" according to the JLS and that's what counts.

From the JLS 3rd Edition:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String (§3.10.5)
  • Casts to primitive types and casts to type String
  • The unary operators +, -, ~, and ! (but not ++ or --)
  • The multiplicative operators *, /, and %
  • The additive operators + and -
  • The shift operators <<, >>, and >>>
  • The relational operators <, <=, >, and >= (but not instanceof)
  • The equality operators == and !=
  • The bitwise and logical operators &, ^, and |
  • The conditional-and operator &amp;amp;amp;& and the conditional-or operator ||
  • The ternary conditional operator ? :
  • Parenthesized expressions whose contained expression is a constant expression.
  • Simple names that refer to constant variables (§4.12.4).
  • Qualified names of the form TypeName . Identifier that refer to constant variables (§4.12.4).
I posted this info as a comment on his site, but since comments aren't visible I decided to post this on my own blog.

Enjoy and Happy New Year to all.