问题
I was working on switch case.
If we use class.getName(), then, I am getting error that "case expressions must be constant expressions" as follows:
switch(param.getClass().getName())
{
case String.class.getName():
// to do
break;
}
Even if we do following, take string class name in a constant, then also, getting same error:
public static final String PARAM_NAME = String.class.getName();
switch(param.getClass().getName())
{
case PARAM_NAME:
// to do
break;
}
But, if I do following, use the string literal "java.lang.String", there is not error:
public static final String PARAM_NAME = "java.lang.String";
Can anybody please explain this, why its not taking first two cases and taking the last one? Thanks in advance.
回答1:
classObject.getName()
is a method call, and the results of method calls are by definition not compile-time constants. A string literal is a compile-time constant.
Note that while many situations could take a static final
reference as a constant for the lifetime of the program, a switch
has to have its options hard-coded at compile-time. The value of a case
target must be either an enum value or a (compile-time) ConstantExpression.
回答2:
Every case label must be a "constant expression". What is "constant expression" is defined in Java Language Standard, §15.28 Constant Expressions:
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
...
- Simple names that refer to constant variables
No method calls are listed there, so method call result cannot be the constant expression even if the method is trivial. But "Simple names that refer to constant variables" are listed here, so reference to the constant variable is also a constant.
回答3:
The reason this does not work is that the value of the case
to switch on needs to be known at compile-time (because it is hard-coded and inlined in the bytecode).
String.class.getName()
is a method call that gets evaluated at runtime. Yes, static final
guarantees that it does not change after the class is initially loaded. But all that is long after compile-time.
The compiler never calls any code from application source code (with the possible exception of annotation processing). It only compiles it.
来源:https://stackoverflow.com/questions/33646494/java-8-difference-between-class-getname-and-string-literal