aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Switch statement - Constant expression Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Switch statement - Constant expression" Watch "Switch statement - Constant expression" New topic
Author

Switch statement - Constant expression

Thomas De Vos
stable boy
Ranch Hand

Joined: Apr 12, 2003
Posts: 425
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 ]

    Try your free <a href="http://www.javacertificate.com" target="_blank" rel="nofollow">SCJP 1.4</a> certification centre.<br />Try your free <a href="http://www.j2eecertificate.com" target="_blank" rel="nofollow">SCWCD</a> certification centre.<br />Try your free <a href="http://www.ejbcertificate.com" target="_blank" rel="nofollow">SCBCD</a> certification centre.<br />Try your <a href="http://www.webspherecertificate.com" target="_blank" rel="nofollow">Websphere (Test 285) </a> certification centre.<br />Try your <a href="http://www.j2mecertificate.com" target="_blank" rel="nofollow">SCMAD</a> certification centre. (New)<br /> <br /><a href="http://blogs.javacertificate.com" target="_blank" rel="nofollow">Java/J2EE Certification Blogging</a>
    Mark Spritzler
    ranger
    Sheriff

    Joined: Feb 05, 2001
    Posts: 17260
        
        6

    "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


    Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
    How to Ask Questions the Smart Way FAQ
    Joyce Lee
    Ranch Hand

    Joined: Jul 11, 2003
    Posts: 1392
    [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
    Ranch Hand

    Joined: Apr 12, 2003
    Posts: 425
    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
    Ranch Hand

    Joined: Apr 12, 2003
    Posts: 425
    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 ]
    Barry Gaunt
    Ranch Hand

    Joined: Aug 03, 2002
    Posts: 7729
    The case label must be a compile-time constant expression. I guess the boxing/unboxing cannot be considered to be done at compile-time.


    Ask a Meaningful Question and HowToAskQuestionsOnJavaRanch
    Getting someone to think and try something out is much more useful than just telling them the answer.
    Joyce Lee
    Ranch Hand

    Joined: Jul 11, 2003
    Posts: 1392
    [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
    Ranch Hand

    Joined: Apr 12, 2003
    Posts: 425
    Joyce,

    That makes perfect sense. Thanks.

    Barry,

    Thanks, the difference is indeed related to the compile-time conversion where as unboxing is at runtime.
    Jim Yingst
    Wanderer
    Sheriff

    Joined: Jan 30, 2000
    Posts: 18671
    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.


    "I'm not back." - Bill Harding, Twister
    karsten spant
    Greenhorn

    Joined: Jan 06, 2006
    Posts: 1
    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.
    jiju ka
    Ranch Hand

    Joined: Oct 12, 2004
    Posts: 306
    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
    Sheriff

    Joined: Jan 30, 2000
    Posts: 18671
    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.
    Simi gupta
    Greenhorn

    Joined: Oct 17, 2005
    Posts: 7
    Line no 4 & 5 in above code doesn't compile for me.
    am i doing something wrong?
    Barry Gaunt
    Ranch Hand

    Joined: Aug 03, 2002
    Posts: 7729
    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

    Joined: Oct 17, 2005
    Posts: 7
    Well, i'm using java version "1.4.2_06".
    Thomas De Vos
    stable boy
    Ranch Hand

    Joined: Apr 12, 2003
    Posts: 425
    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

    Joined: Oct 12, 2004
    Posts: 306
    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".
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Switch statement - Constant expression