为什么内部类不能使用静态初始化器?

Quoth JLS#8.1.3 :

内部类可能不会声明静态初始化器 (第8.7节 )……

这表现如下:

class A { class B { static { // Compile-time Error: Cannot define static initializer in inner type AB System.out.println("Class is initializing..."); } } } 

既然Java的内部(非静态)类是由类加载器加载的 ,就像其他类一样,为什么我们不能为它们安装静态初始化器?

这种限制背后的原因是什么?

我认为这是因为Inner类本身不是静态的。 从Java的角度来看 它是一个实例变量,我想是的 (1)类加载器不是设计用于爬入内部非静态类来查找和初始化potentiel静态对象。

但它不是不可能的问题,请看下面的例子:

 public class Outer { public static class Inner { Outer owner; static String constant; { constant = "foo"; } private Inner(Outer owner) { if (owner == null) { throw new NullPointerException(); } this.owner = owner; } } public Inner newInner() { return new Inner(this); } } 

甚至没有警告,因为Inner声明为静态。

但是第二眼看,它有一个指向封闭Outer实例的指针,只能通过Outer创建,因为它只有一个私有构造函数,并且它的所有者不能为null。 从程序员的角度来看,它具有非静态内部类的所有约束,并且可以像一个一样使用(除了像Outer.this这样的特殊习语),但从编译器的角度来看,它是静态的,它的静态字段将是在第一次Outer初始化时正确初始化。

(1):Pacerier在下面解释了为什么这是不正确的。

无有效使用

只是我提出的意见,赞成争论/辩论

请阅读以下主题。

这解释了为什么Java禁止内部类中的静态字段

IMO同样的原因也适用于static initializer 。 毕竟,创建问题的是关键字static

除了上面提到的原因,我还可以给出另一个蹩脚的理由
static initializer的名称为我们提供了何时以及为何使用此块的提示。 一个不是简单地使用静态初始化程序块来打印hello world [ 在这里插入meme ]。
使用此块的主要原因显然是初始化静态变量。

现在作为内部类/非静态嵌套类不允许静态变量,允许静态初始化器有什么意义?

根据定义存在矛盾:

来自JLS§8.1.3

当且仅当包含语句或表达式的最内层方法,构造函数,实例初始化程序,静态初始化程序,字段初始值设定项或显式构造函数调用语句是静态方法,静态初始化程序,变量初始化程序时,语句或表达式才会出现在静态上下文中静态变量或显式构造函数调用语句(第8.8.7节)。

当内部类(其声明不在静态上下文中出现)引用作为词法封闭类的成员的实例变量时,将使用相应的词法封闭实例的变量。