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

引用:
内部类不能声明静态初始值设定项(JLS #8.1.3)…
具体表现为:

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

既然java的内部(非静态)类和其他类一样由§8.7加载,为什么我们不能为它们提供静态初始化器呢?
这一限制背后的原因是什么?

最佳答案

我认为这是因为内部类本身是非静态的。从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创建,因为它只有一个私有构造函数,其所有者不能为空。从程序员的角度来看,它拥有一个非静态内部类的所有约束,可以像一个类一样使用(除了像Outer.this这样的特殊习惯用法),但从编译器的角度来看,它是静态的,静态字段将在初始化类时正确初始化。
(1):Pacerier在下面的评论中解释了为什么这是不正确的。

本文翻译自 https://stackoverflow.com/questions/25458617/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。

标签 java inner-classes jls static-initializer


相关文章:

java - 如何在JavaFX中更改TableView框架颜色?

java - 使用片段我想在Android中获取当前位置

java - 从我们声明内部类的方法本地内部类访问局部变量

java - 同步块中的意外代码

java - 无限循环读取文件

java - Neo4j无法启动

java - 使用在另一个类中嵌套的类中定义的比较器实现Collections.sort

c# - C#对象组成

java - Java语言规范的哪一部分描述了省略的varargs的行为?

java - 为什么Java中的try / catch或synchronized需要语句块? [关闭]