为什么编译时间常量仅限于原语和字符串?

Why compile time constants limited to only primitives and Strings?

这只是出于好奇,我想我也知道答案,但只是想验证并了解其他观点。

Compile time constants and variables tells that compile time constants are limited to only primitive types and Strings. Why so even if I declare a reference of some type A as final ( final A aObj = new A(); )? Is it because classes are not loaded yet or something else? There are so many other immutable classes in JDK , Complete List of immutable JDK classes? ,为什么不包括那些?

因为对象(可变或不可变)的构造可能会产生必须在运行时发生的副作用。 String 是例外,因为 Java 语言假定这永远不会发生。它的特殊之处还在于它是 Java 语言规范所依赖的少数 类 之一;即在处理文字时,以及某些类型的 switch 语句(Java 6 及更高版本)的语义。

后者与 "compile time constant" 特别相关,因为开关臂表达式需要是编译时常量表达式。

其他几个因素:

  • 编译时常量的处理对于编译器和运行时 JVM 来说都更加复杂

  • 编译时常量在增量编译代码时可能会出现意外行为,因此限制发生这种行为的情况是有益的(对程序员而言),

  • 使更多类型有资格成为编译时常量可能没有太多实际好处。