因此,如果我有一个static final Object CONSTANT = null
,由于某种原因,如果我在另一段代码doSomething(CONSTANT)
中引用它,那么它将不会在编译期间嵌入到代码中。因此,编译后不是doSomething(null)
,而是doSomething(CONSTANT)
。
答案 0 :(得分:17)
您的CONSTANT
不是编译时常量,因为JLS 表示不是。可以在常量表达式中使用的唯一类型是基本类型和String
。
它的意义在于Object
实例(通常)具有语义上重要的对象标识,可以将其与其他Object
实例区分开来。此对象标识不能在类文件中编码...或者至少,它不能使用当前的类文件格式进行编码。 (如果可以,会有各种其他问题......)
值null
可以(理论上)作为特例处理,除了没有太多意义。具体而言,您不能在语言学角度需要(或有利)“编译时间常数”的任何上下文中使用null
。例如:
null
作为case
表达。==
不是常量表达式,因此不能将它用于Java“条件编译”习惯用法,其中if
使用常量表达式作为条件。 (除了null == null
不是一个有用的条件......)就内联而言,虽然“常量”不能在字节码中内联(因为关于“常量表达式”是什么的JLS规则),JIT编译器的优化器将被允许这样做,并且< em> may 实际上是这样做的......如果有明显的性能优势的话。
参考:
答案 1 :(得分:4)
在您的情况下, CONSTANT 不是编译时常量。
编译时常量是一个常量,它的值在编译时是已知的 它不会进一步改变,然后编译器在任何地方替换常量名称 在代码中有它的价值。
通常,使用final声明的基本类型或字符串文字被编译器视为编译时常量。 例如:
final int a=10;
final String constant =”this is compile time const”;
这两个都是编译时常量,我们可以在switch语句的case标签
中使用编译时常量表达式
非编译时常量的示例
final String xyz = new String(”this is not a compile time const");
这里xyz字符串对象不是编译时常量。因为这个'xyz'字符串对象将在运行时创建,这里编译器只知道引用而不是字符串对象。
同样适用于静态最终对象CONSTANT = null
正在加载JLS
null文字的类型是null类型;其值是空引用。