为什么 Java 禁止在内部类中使用静态字段?

2022-08-31 11:14:19
class OuterClass {
 class InnerClass {
  static int i = 100; // compile error
  static void f() { } // compile error
 }
} 

虽然不能使用 访问静态字段,但如果要记录应该是静态的内容,例如创建的 InnerClass 对象的数量,那么使该字段成为静态会很有帮助。那么,为什么Java禁止在内部类中使用静态字段/方法呢?OuterClass.InnerClass.i

编辑:我知道如何使编译器对静态嵌套类(或静态内部类)感到满意,但我想知道的是,如果有人对它有更多的了解,为什么java禁止内部类(或普通内部类)中的静态字段/方法。


答案 1

我想知道的是为什么java禁止内部类中的静态字段/方法

因为这些内部类是“实例”内部类。也就是说,它们类似于封闭对象的实例属性。

由于它们是“实例”类,因此允许功能没有任何意义,因为它首先意味着在没有实例的情况下工作。staticstatic

这就像您尝试同时创建静态/实例属性一样。

举个例子:

class Employee {
    public String name;
}

如果创建两个雇员实例:

Employee a = new Employee(); 
a.name = "Oscar";

Employee b = new Employee();
b.name = "jcyang";

很明显,为什么每个人都有自己的财产价值,对吧?name

内部类也是如此;每个内部类实例都独立于另一个内部类实例。

因此,如果尝试创建 class 属性,则无法在两个不同的实例之间共享该值。counter

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

当您创建实例时,在上面的示例中,静态变量的正确值是什么?无法确定它,因为类的存在完全取决于每个封闭对象。abcountInnerData

这就是为什么,当类被声明为 时,它不再需要一个活的实例,来生存自己。现在没有依赖关系,您可以自由声明静态属性。static

我认为这听起来很重复,但如果你考虑实例与.class属性之间的差异,这将是有道理的。


答案 2

内部类背后的思想是在封闭实例的上下文中运行。不知何故,允许静态变量和方法与这种动机相矛盾吗?

8.1.2 内部类和封闭实例

内部类是未显式或隐式声明为静态的嵌套类。内部类不能声明静态初始值设定项 (§8.7) 或成员接口。内部类不能声明静态成员,除非它们是编译时常量字段 (§15.28)。


推荐