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

标签 java inner-classes jls static-initializer

Quot JLS #8.1.3 :

Inner classes may not declare static initializers (§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 加载就像所有其他类一样,为什么我们不能为它们提供静态初始值设定项?

此限制背后的原因是什么?

最佳答案

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

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

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 创建,因为它只有一个私有(private)构造函数,而它的所有者不能为空。从程序员的角度来看,它具有非静态内部类的所有约束并且可以像一个一样使用(除了像 Outer.this 这样的特殊习语),但从编译器的角度来看它是静态的,它的静态字段将在首先 Outer 类初始化时正确初始化。

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

关于java - 为什么内部类不能使用静态初始化器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25458617/

相关文章:

java - Builder (android.content.Context) in builder 不能应用到?

java - Android 上复杂数学过程中的 Stackoverflow

java - 如何从SD卡或android中的指定路径读取csv文件

java - Java 中的公共(public)内部类与私有(private)内部类

java - 为什么在检查编译时常量时,一个分支足以解析变量赋值,但不足以从该分支返回?

java - 阻止用户在java扫描仪中输入数字?

java - jMockit对私有(private)类的访问

java - 如果在外部类的方法中声明了内部类,如何初始化内部类的实例?

java - 为什么这个程序用 Java 7 而不是 Java 8 编译?

java - Java JLS 是否指定提升原始包装器类型?