为什么允许编译时常量在非静态内部类中变为静态?

假设我们有如下代码。

public class Outer{ class Inner{ public static final String s = "abc"; } static class Nested{ public static final SomeOtherClass instance = new SomeOtherClass(); } } 

我理解要实例化非静态内部类对象,需要外部 对象static表示与类相关,为了访问它,不需要实例化对象。 只有在实例化外部类的对象后才能使用非静态内部类。 在其中包含任何静态引用可能没有意义。

我的问题:

  1. 非静态内部类可以在没有任何外部类的显式对象的情况下加载吗?

  2. 为什么编译时间常量 (字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)允许在非静态内部类中变为静态

编辑:为什么不允许非编译时常量变为静态,我知道它是按照JLS,但只是想知道会出现什么问题,制定这个规则的意图是什么。

  1. 非静态内部类可以在没有任何外部类的显式对象的情况下加载吗?

是。 创建内部类的实例需要外部类的实例。 但是在创建任何实例之前都可以加载这两个类。

  1. 为什么我们可以在非静态内部类中使编译时常量(字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)是静态的?

语言规范允许常量变量的此exception。 从Java语言规范,第8.1.3节:“内部类和封闭实例” :

如果内部类声明显式或隐式静态的成员,则它是编译时错误,除非该成员是常量变量(第4.12.4节)。

字符串变量可以是常量,因为第4.12.4节“ final变量” :

常量变量是基本类型的最终变量或用常量表达式初始化的String类型(第15.28节)。

问题1 – 非静态内部类可以在没有任何外部类的显式对象的情况下加载吗?

是的,您可以通过这种方式加载非静态内部类,请看下面的示例:

 class MyObject { class InnerObject { static final String prop = "SOME INNER VALUE"; } static void doLoad() { System.out.println(InnerObject.prop); } } 

事情是没有太多理由这样做,因为非静态内部类不允许有任何静态块,方法,字段,如果这些不是最终的,如下面的问题。

问题2 – 为什么我们可以在非静态内部类中使编译时常量(字符串文字,因为它们在字符串池和基元类型中以特殊方式处理)是静态的?

Java的设计使您可以在非静态内部类中使用static final字段。