java 8:class.getName()和String literal之间的区别

Kri*_*mar 6 java constants string-literals switch-statement java-8

我正在研究开关盒.

如果我们使用class.getName(),那么,我得到的错误是"case表达式必须是常量表达式",如下所示:

switch(param.getClass().getName())
    {
        case String.class.getName():
            // to do
            break;
    }
Run Code Online (Sandbox Code Playgroud)

即使我们执行以下操作,也请在常量中获取字符串类名,然后获取相同的错误:

public static final String PARAM_NAME = String.class.getName();
switch(param.getClass().getName())
    {
        case PARAM_NAME:
            // to do
            break;
    }
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,请使用字符串文字"java.lang.String",没有错误:

public static final String PARAM_NAME = "java.lang.String";
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释一下,为什么不采取前两个案件并采取最后一个案例?提前致谢.

chr*_*ke- 8

classObject.getName()是方法调用,方法调用的结果根据定义不是编译时常量.字符串文字编译时常量.

请注意,虽然许多情况可能会将static final引用作为程序生命周期的常量,但switch必须在编译时对其选项进行硬编码.case目标的值必须是枚举值或(编译时)ConstantExpression.

  • `final`变量是一个编译时常量,当且仅当它立即用编译时常量初始化时.请注意,它不必是"静态",它甚至不必是一个字段,该规则也适用于局部变量. (3认同)
  • @KrishnaKumar一个`static final`字段不一定是编译时常量,即使出于实际目的,它在运行时也是一个常量. (2认同)

Tag*_*eev 6

每个案例标签必须是"常量表达式".什么是"常量表达式"在Java语言标准中定义,§15.28常量表达式:

编译时常量表达式是表示基本类型的值的表达式或不突然完成的字符串,仅使用以下内容组成:

  • 原始类型的文字和String类型的文字

...

  • 引用常量变量的简单名称

这里没有列出任何方法调用,因此即使方法很简单,方法调用结果也不能是常量表达式.但是这里列出了"引用常量变量的简单名称",因此对常量变量的引用也是常量.