我们已经明白,非静态内部类不能包含任何具有static
关键字的成员。然而,我们看到static
成员变量与final
正在被使用和鼓励。任何人都可以解释原因吗?
另一个观察结果:
final static String abc = "I Love Food"; //works fine
,而:
final static String abc = null; //is discouraged and gives error.
答案 0 :(得分:2)
关于内部类中静态/非静态成员的使用规则,请阅读以下JLS section (§8.1.3)。
内部类可能不会声明静态初始化器(第8.7节)或成员 接口,或发生编译时错误。
内部类可能不会声明静态成员,除非它们是常量 变量(§4.12.4),或发生编译时错误。
请注意上面这一行 - “除非它们是常数变量”,它会回答您的问题。当您将基元或字符串声明为public static final
时,它将变为“常量变量”,因此您可以在非静态内部类中使用它,因为它不会破坏它编制规则。
现在,为什么它不会破坏编译规则,因为当你声明一个常量变量并初始化它时,编译器可以确定地说这将是这个变量的值,而如果你没有初始化它,那么编译器就不能确定地说这将是此变量的值,并且无法确定它是否可以在运行时进行修改,并且在分配后无法更改最终值。
中读取与最终变量相关的规则答案 1 :(得分:1)
我们已经明白,非静态内部类不能包含任何具有
static
关键字的成员。
显然你的理解并不完整。 JLS版本8的8.1.3节部分指定了
如果内部类声明显式或隐式静态的成员,则该编译时错误,除非该成员是常量变量(§4.12.4)。
(强调补充。)因此内部类可以拥有静态成员;对他们有相当强烈的限制。
但是我们看到,
static
成员变量与final
正在被使用和鼓励。任何人都可以解释原因吗?
(原文中的重点。)我认为我经常看不到这种用法,本身。然而,这是保持这些常数范围缩小的明智方法,这是一种很好的做法。
您还要询问为什么static final
内部成员无法初始化为null
。我不能提供理由,但实际规则在JLS中,在4.12.4节中的“常量变量”(由前面的摘录引用)的定义中详细说明:
常量变量是基本类型或类型的最终变量
String
用常量表达式初始化(§15.28)。
当然,这取决于the definition of a "constant expression",整体呈现有点冗长。它归结为原始或String
类型的表达式,它只涉及整数文字,字符串文字,指定常量变量的名称以及相当大的Java运算符子集。这就是我们的观点: null
既不是原始类型也不是类型String
,因此它不能出现在常量表达式 中,因此,如果变量具有null
或包含null
的表达式作为其初始值,则变量不是“常量变量”。这样的变量,不是常量变量,不能出现在内部类中。
答案 2 :(得分:0)
如果您查看此接受的答案Why does Java prohibit static fields in inner classes,引用的部分将为您提供答案。 final static
字段被视为Java的编译时常量。