java 8: difference between class.getName() and String literal [duplicate]

五迷三道 提交于 2020-06-22 18:54:19

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!