• 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

Case statement

 
Ranch Hand
Posts: 61
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi all
True or False
The argument for a "case" statement must be a constant or a constant expression which can be evaluated at compile time.
pleas explain above question's answer
 
Ranch Hand
Posts: 1561
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hmm... it's gotta be a compile time constant, so I'd say False.

Result:
B.java:10: constant expression required
case test : System.out.println("Check this out");
^
1 error

Now, let's modify it a little

Result:
B.java:11: constant expression required
case test : System.out.println("Check this out");
^
1 error

Didn't like it either. Now

Compiles and prints "Check this out".
As you can see, the compiler is not happy enough with final. It must be a compile time constant.
does that help?
[ July 29, 2003: Message edited by: Andres Gonzalez ]
 
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Would an int Literal be considered a compile-time constant or compile-time expression? If so, I agree. If not, I don't, since int literals are also allowed.
I tried all sorts of wacky ways to find a way around the compile-time constants, but couldn't bypass it even with things like this:

As I mentioned, if you uncomment the case line, it dies the expected miserable death at compile time.
I tried other things like using the static block (knew that was doomed).
Here was a rather interesting one....this PROVES it constructs case tests at COMPILE time!!
Each class must be in its own file---
First:

Second:

Compile the two programs (obviously, the first one must be compiled first since the second one refers to it) and then run the second program. Note the results.
Now, go back to the first file, switch the 1 and the 3, and compile ONLY that file. Now run the second file again...you'll see that the output does not change. Now, recompile the second file. You suddenly see the expected changes from swapping the two values in the first file. (note that I don't have a break, so one scenario spits out two numbers and the other spits out one number to help ensure you notice the difference).
On one hand, it is pretty cool...on the other, it is pretty logical that it works that way, since the constants declared in the second file will compile based on their value at the point in time that the second file is actually compiled...but it serves as proof, I think, that the case evaluates/uses ONLY compile-time constants/literals.
Ross
 
Andres Gonzalez
Ranch Hand
Posts: 1561
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Good example Ross !
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A switch label looks like this,
case ConstantExpression :
default:
where ConstantExpression is defined by JLS 15.28 Constant Expression
Pay special attention to these two

Literals of primitive type and literals of type String
Simple names that refer to final variables whose initializers are constant expressions

 
Ross Goldberg
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Except that you can't switch on a String.
 
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Theoritically, test is a compile time constant in this example as well. It can not be reassigned. However, compiler is not smart enough to deduce that.
Ron: You tried it to limit
[ July 29, 2003: Message edited by: Barkat Mardhani ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Constant expressions are often called compile-time constants, because the value of the expression is known at compile-time.
final int x1 = 1;
final short x2 = 1 << 2;
final int x3 = x1;
final int x4 = x1 + x2;
The values of x1, x2, x3, x4, x1 + x2 + x3 + x4 are known at compile-time.
int y1 = 1; //not final
final int y2; //no variable initializer (initialized in constructor)
final int y3 = y2; //initializer is not a constant expression
The values of y1, y2, y3, y1 + y2 + y3 are computed at run-time.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

y is a compile-time constant. At run-time 2 is stored in x.
z is not a compile-time constant. At run-time the value of z is loaded from memory and stored in x.
[ July 30, 2003: Message edited by: Marlene Miller ]
 
Ranch Hand
Posts: 247
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Blank final variables (static or not) can NOT be used in case statements.
Particularly, in case of static variables:
this won't compile:

but code above will:

For static variables, you may refer to following link:
https://coderanch.com/t/242516/java-programmer-SCJP/certification/CASE-STATIC-initializer
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why the following code get "constant expression required" error. Thought typeID is constant. thx.
class CommandCodes {
public static final int typeID = 1;
}
public class SwitchTestNotWork {
public static void main(String[] args) {
CommandCodes cmd = new CommandCodes();
int value = 1;
switch (value) {
case cmd.typeID:
System.out.println("success");
break;
default:
System.out.println("failure");
break;
}
}
}
 
Barkat Mardhani
Ranch Hand
Posts: 787
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. cmd is referring to an object of given class
2. therefore cmd can refer to any object of given class
3. therefore compiler thinks that cmd.typeid is variable even though typeid itself is constant.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch Diane.
case CommandCodes.typeID:
will compile however; cmd.typeID is not a compile constant expression according to JLS 15.28:


# Simple names that refer to final variables whose initializers are constant expressions
# Qualified names of the form TypeName . Identifier that refer to final variables whose initializers are constant expressions


cmd.typeID is neither a simple name nor a TypeName.Identifier
[ July 30, 2003: Message edited by: Jose Botella ]
 
Diane Cheng
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barkat and Jose, thanks for your replies.
 
Ross Goldberg
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barkat, Jose:
Barkat said:
1. cmd is referring to an object of given class
2. therefore cmd can refer to any object of given class
3. therefore compiler thinks that cmd.typeid is variable even though typeid itself is constant.
The thing is, I recall reading in K & B that when you refer to a static through a named instance, the compiler simply allows that as a convenience function and it actually calls it through the class type of the instance. That being the case, wouldn't it really be converting cmd.typeid to Cmd.typeid and thus allow it?
If not, why doesn't it work that way?
Ross
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The compiler access cmd.typeID in the same way as CommandCodes.typeID, except that first loads the reference to cmd object in the operand stack, and then descard it:

I guess that the compiler cannot think of cmd.typeID as a compile constant because is has no way to check that cmd is not pointing to null at runtime. If the field is not static that would yield an error.
 
reply
    Bookmark Topic Watch Topic
  • New Topic