为什么null不是编译时常量?
因此,如果我有一个static final Object CONSTANT = null
,由于某种原因,如果我在另一段代码中引用它,如doSomething(CONSTANT)
,它将不会在编译期间嵌入到代码中。 所以编译后不是doSomething(null)
,而是doSomething(CONSTANT)
。
您的CONSTANT
不是编译时常量,因为JLS 说它不是。 可以在常量表达式中使用的唯一类型是基本类型和String
。
它的意义在于Object
实例(通常)具有语义上重要的对象标识,可以将其与其他Object
实例区分开来。 此对象标识不能在类文件中编码…或者至少,它不能使用当前的类文件格式进行编码。 (如果可以,会有各种其他问题……)
值null
(理论上)可以作为特例处理,除了没有太多意义。 具体而言,您不能在语言学角度要求(或有利)“编译时间常数”的任何上下文中使用null
。 例如:
- 您不能将
null
作为case
表达式。 - 由于引用类型的
==
不是常量表达式,因此不能将它用于Java“条件编译”惯用法,该惯用法涉及使用常量表达式作为条件的if
。 (除了null == null
不是一个有用的条件……)
就内联而言,虽然“常量”不能在字节码中内联(因为关于“常量表达式”是什么的JLS规则),JIT编译器的优化器将被允许执行此操作,并且实际上可以执行此操作……如果有切实的性能优势。
参考:
- JLS 15.28 – 常量表达式
在您的情况下, CONSTANT不是编译时间常量。
编译时常量是一个常量,它的值在编译时是已知的并且不会进一步改变,然后编译器将代码中的常量名称替换为其值。
通常,使用final声明的基本类型或字符串文字将被编译器视为编译时常量。 例:
final int a=10; final String constant =”this is compile time const”;
这两者都是编译时常量,我们可以在switch语句的case标签中使用Compile-time常量表达式
非编译时常量的示例
final String xyz = new String(”this is not a compile time const");
这里xyz字符串对象不是编译时常量。因为这个’xyz’字符串对象将在运行时创建,这里编译器只知道引用而不是字符串对象。
这同样适用于您的静态最终Object CONSTANT = null
加入JLS
null文字的类型是null类型;其值是空引用。
- CubicCurve2D连接两个JInternalFrame实例
- Java Beans作为数据存储类设计不好吗?
- Maven / Surefire没有找到unit testing
- Thread.sleep等待超过预期
- 如何@autowire一些bean进入JsonSerializer?
- 对doFinal的一些调用有badPaddingException。 不是全部。 相同的输入
- hibernate-validator中的exception。 嵌套exception是java.lang.NoClassDefFoundError:ConfigurationImpl
- Spring Boot,使用@Configurable和加载时间编织将@Autowire转换为非托管类
- 访客模式可以用于执行通用双重调度吗?