为什么 null 不是编译时常量?
因此,如果我有一个,出于某种原因,如果我在另一段代码中引用它,例如,在编译过程中,它不会内联到代码中。因此,它不是在编译之后,而是.static final Object CONSTANT = null
doSomething(CONSTANT)
doSomething(null)
doSomething(CONSTANT)
因此,如果我有一个,出于某种原因,如果我在另一段代码中引用它,例如,在编译过程中,它不会内联到代码中。因此,它不是在编译之后,而是.static final Object CONSTANT = null
doSomething(CONSTANT)
doSomething(null)
doSomething(CONSTANT)
你不是编译时常量,因为JLS说它不是。唯一可以在常量表达式中使用的类型是基元类型和 。CONSTANT
String
它的意义在于,实例(通常)具有语义上显着的对象标识,可将其与其他实例区分开来。此对象标识不能在类文件中编码...或者至少,它不能用当前的类文件格式进行编码。(如果可以的话,还会有各种各样的其他问题......Object
Object
该值(理论上)可以作为特例处理,除了没有太多意义。具体来说,从语言的角度来看,您不能在任何需要(或有利)“编译时常量”的上下文中使用。例如:null
null
null
case
==
if
null == null
就内联而言,虽然“常量”不能内联到字节码中(因为JLS关于什么是“常量表达式”的规则),但JIT编译器的优化器将被允许这样做,并且实际上可以这样做......如果有实实在在的性能优势。
参考:
在你的例子中,常量不是编译时常量。
编译时常量是一个常量,其值在编译时已知,它不会进一步更改,然后编译器将代码中所有位置的常量名称替换为其值。
通常,使用 final 声明的基元类型或字符串文本被编译器视为编译时常量。例:
final int a=10;
final String constant =”this is compile time const”;
这两者都是编译时常量,我们可以在switch语句的标签中使用编译时常量表达式
非编译时常量示例
final String xyz = new String(”this is not a compile time const");
这里的xyz字符串对象不是编译时常量。因为这个'xyz'字符串对象将在运行时创建,而编译器只知道引用而不是字符串对象。
这同样适用于静态最终对象常量 = null
符合 JLS 标准
空文本的类型是空类型;其值是空引用。