为什么我们不能在(非静态)内部类(Java 16之前)中使用静态方法?

2022-08-31 07:40:22

为什么我们不能在非静态内部类中使用静态方法?

public class Foo {
    class Bar {
        static void method() {} // Compiler error
    }
}

如果我使内部类静态化,它就会起作用。为什么?

public class Foo {
    static class Bar { // now static
        static void method() {}
    }
}

在Java 16+中,这两者都是有效的。


答案 1

由于内部类的实例与其外部类的实例隐式关联,因此它本身无法定义任何静态方法。由于静态嵌套类不能直接引用其封闭类中定义的实例变量或方法,因此它只能通过对象引用来使用它们,因此在静态嵌套类中声明静态方法是安全的。


答案 2

在非静态内部类中允许静态方法没有多大意义;您将如何访问它?如果不通过外部类实例,则无法访问(至少在最初)非静态内部类实例。没有纯静态的方法来创建非静态的内部类。

对于外部类,您可以访问如下静态方法:Outertest()

Outer.test();

对于静态内部类,您可以像这样访问其静态方法:InnerinnerTest()

Outer.Inner.innerTest();

但是,如果不是静态的,则现在没有纯静态的方式来引用该方法。非静态内部类绑定到其外部类的特定实例。函数与常量的不同之处在于,对 的引用保证是明确的,而函数调用则不是。假设您有该调用 ,该调用在 中定义。如果尝试调用该静态函数,则现在具有对 Inner 类的不明确引用。也就是说,在内部类的哪个实例上调用静态函数?这很重要。看,由于对外部对象的隐式引用,没有真正静态的方式来引用该静态方法。InnerinnertestOuter.Inner.CONSTANTOuter.Inner.staticFunction();Inner.staticFunction()getState()Outer

Paul Bellora说得对,语言设计者本可以允许这样做。然后,他们必须小心地禁止在非静态内部类的静态方法中对外部类的隐式引用进行任何访问。此时,如果不能引用外部类(静态引用除外),那么作为内部类的价值是什么?如果静态访问很好,那么为什么不声明整个内部类是静态的呢?如果只是使内部类本身成为静态的,则没有对外部类的隐式引用,并且不再具有这种多义性。

如果你真的需要在非静态内部类上使用静态方法,那么你可能需要重新考虑你的设计。


推荐