Quoth JLS #8.1.3:
内部类可能无法声明静态初始值设定项(§8.7)......
这证明了这一点:
class A {
class B {
static { // Compile-time Error: Cannot define static initializer in inner type A.B
System.out.println("Class is initializing...");
}
}
}
既然Java的内部(非静态)类是由class loaders加载的,就像其他所有类一样,为什么我们不能为它们提供静态初始化器?
这种限制背后的原因是什么?
答案 0 :(得分:0)
我认为这是因为Inner类本身不是静态的。从Java的角度来看,它是一个实例变量,我认为 (1)类加载器不是设计为爬进内部非静态类来查找和初始化potentiel static对象。
但这不是不可能性问题,请看下面的例子:
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在下面解释了为什么这是不正确的。
答案 1 :(得分:0)
无有效使用
只是我提出的意见,赞成争论/辩论
请阅读以下主题。
This explains, Why does Java prohibit static fields in inner classes
IMO同样的理由也适用于static initializer
。毕竟,创建问题的关键是关键字static
。
除了上面提到的原因,我还可以给出另一个蹩脚的理由
块static initializer
的名称为我们提供了使用此块的时间和原因的提示。一个不是简单地使用静态初始化块来打印hello world [在这里插入meme ]。
使用此块的主要原因显然是初始化静态变量。
现在内部类/非静态嵌套类不允许使用静态变量,允许静态初始化器有什么意义?
答案 2 :(得分:-1)
根据定义存在矛盾:
来自JLS §8.1.3:
语句或表达式出现在静态上下文中,当且仅当 最里面的方法,构造函数,实例初始化器,静态 初始化程序,字段初始值设定项或显式构造函数调用 括起语句或表达式的语句是静态方法,a 静态初始化程序,静态变量的变量初始值设定项,或 显式构造函数调用语句(第8.8.7节)。
...
当一个内部类(其声明不在静态中发生) context)指的是作为a的成员的实例变量 词汇封闭类,词汇对应的变量 使用封闭实例。