GeeCON Prague 2014*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Case statement 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 "Case statement" Watch "Case statement" New topic
Author

Case statement

Saman Perera
Ranch Hand

Joined: Jul 15, 2003
Posts: 61
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
Andres Gonzalez
Ranch Hand

Joined: Nov 27, 2001
Posts: 1561
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 ]

I'm not going to be a Rock Star. I'm going to be a LEGEND! --Freddie Mercury
Ross Goldberg
Ranch Hand

Joined: Jul 09, 2003
Posts: 63
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

Joined: Nov 27, 2001
Posts: 1561
Good example Ross !
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Jul 09, 2003
Posts: 63
Except that you can't switch on a String.
Barkat Mardhani
Ranch Hand

Joined: Aug 05, 2002
Posts: 787

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

Joined: Mar 05, 2003
Posts: 1391
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

Joined: Mar 05, 2003
Posts: 1391

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 ]
cyril vidal
Ranch Hand

Joined: Jul 02, 2003
Posts: 247
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:
http://www.coderanch.com/t/242516/java-programmer-SCJP/certification/CASE-STATIC-initializer


SCJP 1.4, SCWCD, SCBCD, IBM XML, IBM Websphere 285, IBM Websphere 287
Diane Cheng
Greenhorn

Joined: Jul 30, 2003
Posts: 7
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

Joined: Aug 05, 2002
Posts: 787
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.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
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 ]

SCJP2. Please Indent your code using UBB Code
Diane Cheng
Greenhorn

Joined: Jul 30, 2003
Posts: 7
Barkat and Jose, thanks for your replies.
Ross Goldberg
Ranch Hand

Joined: Jul 09, 2003
Posts: 63
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

Joined: Jul 03, 2001
Posts: 2120
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.
 
GeeCON Prague 2014
 
subject: Case statement