为什么Java禁止内部类中的静态字段?
class OuterClass {
class InnerClass {
static int i = 100; // compile error
static void f() { } // compile error
}
}
虽然无法使用OuterClass.InnerClass.i
访问静态字段,但是如果我想记录一些应该是静态的内容,例如创建的内部类对象的数量,那么将该字段设置为静态会很有帮助。那么为什么Java禁止内部类中的静态字段/方法呢
编辑:我知道如何使编译器对静态嵌套类(或静态内部类)感到满意,但我想知道的是,如果有人了解更多,为什么java从语言设计和实现两个方面禁止内部类(或普通内部类)中的静态字段/方法
# 1 楼答案
从Java16开始,情况就不再如此了。从JEP 395引用(关于记录定稿):
实际上,以下代码可以用Java16编译(使用16.ea.27进行了尝试):
# 2 楼答案
内部类背后的思想是在封闭实例的上下文中操作。不知何故,允许静态变量和方法与这种动机相矛盾
# 3 楼答案
InnerClass
不能有static
个成员,因为它属于OuterClass
的实例。如果将InnerClass
声明为static
以将其与实例分离,则代码将编译顺便说一句:您仍然可以创建
InnerClass
的实例static
在这个上下文中,允许在没有OuterClass
的封闭实例的情况下发生这种情况# 4 楼答案
因为这些内部类是“实例”内部类。也就是说,它们类似于封闭对象的实例属性
因为它们是“实例”类,所以允许
static
特性没有任何意义,因为static
本来就应该在没有实例的情况下工作就像您同时尝试创建静态/实例属性一样
以以下为例:
如果创建两个employee实例:
很清楚为什么每个属性都有自己的值
name
,对吗内部类也是如此;每个内部类实例都独立于其他内部类实例
因此,如果试图创建
counter
类属性,则无法在两个不同实例之间共享该值在上面的示例中创建实例
a
和b
时,静态变量count
的正确值是多少?无法确定它,因为InnerData
类的存在完全取决于每个封闭对象这就是为什么当类被声明为
static
时,它不再需要一个活实例来活自己。既然没有依赖项,就可以自由声明静态属性我认为这听起来是重复的,但是如果你考虑一下实例属性和类属性之间的区别,这是有意义的
# 5 楼答案
实际上,如果静态字段是常量并且是在编译时编写的,则可以声明静态字段
# 6 楼答案
由于内部类依赖于封闭/外部类的实例,因此需要在初始化内部类之前初始化外部类
This is JLS says about class Initialization.我们需要的是,如果
因此,如果内部类有一个静态字段访问,这将导致初始化内部类,但这不会确保封闭类被初始化
这将违反一些基本规则您可以跳到最后一节(到
two cases
),以避免noob内容关于
static nested
class
的一点是,当一些nested class
是static
时,它的行为在各个方面都与普通类一样,并且与外部类相关联但是} {}的概念是它将与外部/封闭类的{} 相关联。请注意与实例关联的不是类。
现在,与实例关联显然意味着(来自实例变量的概念)它将存在于实例内部,并且在实例之间会有所不同
Inner class
/{现在,当我们将某个对象设为静态时,我们希望它将在加载类时初始化,并且应该在所有实例之间共享。但由于是非静态的,即使内部类本身(您现在肯定可以忘记内部类的实例)也不能与外部/封闭类的所有实例共享(至少在概念上是),那么我们怎么能期望内部类的一些变量会在内部类的所有实例之间共享呢
所以,如果Java允许我们在非静态嵌套类中使用静态变量。将有两个案例
context of instance
(实例变量)的概念。那就不行了李>