• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Switch statement - Constant expression

 
stable boy
Posts: 425
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The following code exhibit doesn't want to compile, even all the requirements are met from the Java language specification according to me.

Some of the rules for the switch labels are:
  • The type of the expression used in the switch statement must be an int, char, short, byte, Integer, Character, Short, Byte or an enum-type, otherwise a compile time error will be generated.
  • A switch label cannot be null.
  • A switch label can only be used once, duplicates are not allowed.
  • Maximum one default switch label can be defined.
  • Every expression in the case statement must be assignable to the type of the switch expression. Types can be assigned through widening, narrowing and (un)boxing conversion.




  • I'm quoting the following from the JLS third Edition:


    Every case constant expression associated with a switch statement must be assignable (�5.2) to the type of the switch Expression.



    If you look at the link from the JLS then year of type Integer is assignable to bootNumber AND year.intValue (which is a constant expression) is assignable to bootNumber, as year is defined as final this is a constant expression.

    What did I not consider, or what is my beatiful compiler considering which I'm overlooking?
    [ January 05, 2006: Message edited by: Thomas De Vos ]
     
    ranger
    Posts: 17347
    11
    Mac IntelliJ IDE Spring
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    "final Integer year = 2007;"

    That doesn't look like a constant to me, just a final variable in a method.

    try using

    static final Integer year = 2007; as a class constant.

    Mark
     
    Ranch Hand
    Posts: 1392
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    [Mark]: static final Integer year = 2007; as a class constant.

    It won't work. It has to be a constant expression of primitive type. For example,



    JLS 3 - 15.28 Constant Expression

    Joyce
     
    Thomas De Vos
    stable boy
    Posts: 425
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Mark,

    That remains exactly the same.

    The variable year is final after the assignment and as such should remain constant, as it cannot be asisgned anymore, during the executing of the main method.

    Could it be because year is a reference and as such is not of the same type as bootNumber? But what about year.intvalue() as this returns a primitive value.

    Only a bit confused ...
     
    Thomas De Vos
    stable boy
    Posts: 425
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Joyce,

    What is the meaning then of assignable in JLS 14.11?

    I understand that anything that can be converted by some kind conversion (widening, narrowing, boxing) and is constant could be used as a switch label.

    The Integer "year" is constant and can be boxed to a primitive type int, which is still constant.
    [ January 05, 2006: Message edited by: Thomas De Vos ]
     
    Ranch Hand
    Posts: 7729
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    The case label must be a compile-time constant expression. I guess the boxing/unboxing cannot be considered to be done at compile-time.
     
    Joyce Lee
    Ranch Hand
    Posts: 1392
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    [Thomas]: The Integer "year" is constant and can be boxed to a primitive type int, which is still constant.



    After unboxing a variable of Integer type, the code becomes


    The value returns from the year.intValue() can be of any value and cannot be determined during compile-time.

    JLS 3 5.1.8 Unboxing Conversion

    Joyce
    [ January 05, 2006: Message edited by: Joyce Lee ]
     
    Thomas De Vos
    stable boy
    Posts: 425
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Joyce,

    That makes perfect sense. Thanks.

    Barry,

    Thanks, the difference is indeed related to the compile-time conversion where as unboxing is at runtime.
     
    Wanderer
    Posts: 18671
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Joyce has this right. Some additional comments:

    [Mark]: static final Integer year = 2007; as a class constant.

    Making this static has nothing to do with whether it's a compile-time constant. It's not part of the requirements listed in JLS 15.28. If we're originally talking about a local variable which we are here), you might as well leave it local. If it's a compile-time constant (which this one isn't), the compiler would end up treating it the same way, putting it in the constants table.

    [Thomas]: What is the meaning then of assignable in JLS 14.11?

    That's one of the additional requirements. They established earlier that the expression after case must be either a constant expressions, defined in 15.28, or an enum constant name. Additionally it must be assignable to the type of the switch expression - but that doesn't change that it must be a constant expression, or an enum. An Integer cannot ever be part of a constant expression. The only reference types which can be constant expressions are Strings - and then only if they obey the other requirements of 15.28.
     
    Greenhorn
    Posts: 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I would like to add some subtle detail: Declaring "year" as final only prohibits the assignment of a new reference to "year":



    But you are using which means your are using the state of "year". Ok, we all know that Integer is immutable, so the state can't be changed.

    But that's the point: You are aiming at the fact, that Integer is immutable but this is an implementation detail. There is no line in the JLS where it is said that Integer has to be immutable. So the JVM can not rely on it.
     
    Ranch Hand
    Posts: 308
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    From
    http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.11


    The body of a switch statement is known as a switch block. Any statement immediately contained by the switch block may be labeled with one or more case or default labels. These labels are said to be associated with the switch statement, as are the values of the constant expressions (�15.28) in the case labels.


    And when we check the constant expressions (�15.28)
    it is only talking about compile time constants.

    Section(�14.11) refers constant expressions.

    What other kinds of constants are there than compile time constants?
    Are all final object refrences except String are non-compile time constants?
    Can you provide links?
     
    Jim Yingst
    Wanderer
    Posts: 18671
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    When most people say "constant", they mean a compile-time constant expression. Some people would also mean things that are constant at runtime but not compile time, such as an immutable object other than String. Or a final primitive field which was initialized from a properties file at runtime. However I think it just causes confusion to call these "constants", since the most common usage seem to be to mean compile-time constant expressions. Let's just stick with that.

    Note that when 14.11 talks about constant expressions (no mention of compile-time), they also give a link to 15.28 which clarifies exactly what they mean. They are really talking about compile-time constant expressions.

    [jiju]: Are all final object refrences except String are non-compile time constants?

    Any object which is not a String is definitely not a compile-time constant expression. And as noted above, I'd prefer not to call them constants at all.

    Can you provide links?

    Section 15.28 already defined what a compile-time constant expression is. Anything outside that definition is not a compile-time constant expression, period.
     
    Greenhorn
    Posts: 7
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Line no 4 & 5 in above code doesn't compile for me.
    am i doing something wrong?
     
    Barry Gaunt
    Ranch Hand
    Posts: 7729
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Simi gupta:
    Line no 4 & 5 in above code doesn't compile for me.
    am i doing something wrong?



    Like not using Java 5.0?
     
    Simi gupta
    Greenhorn
    Posts: 7
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Well, i'm using java version "1.4.2_06".
     
    Thomas De Vos
    stable boy
    Posts: 425
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    That makes sense, the code exhibit will only compile with a Java 5.0 compliant compiler.
    The code exhibit makes use of (auto)boxing which is a new feature to the Java language from Java 5.0 onwards.
    [ January 10, 2006: Message edited by: Thomas De Vos ]
     
    jiju ka
    Ranch Hand
    Posts: 308
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for the explanation. [url=http://"http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.11"]14.11 [/url]was confusing because it is saying "values of the constant expression".

    It should have told "values of the compile time constant expression".
    reply
      Bookmark Topic Watch Topic
    • New Topic