2017-05-24 59 views
0

我们已经明白,非静态内部类不能有任何具有static关键字的成员。然而,我们看到,static成员变量final正在使用和鼓励。谁能解释为什么?为什么Java允许在非静态内部类中使用FINAL的静态变量

另一种看法:

final static String abc = "I Love Food"; //works fine 

而:

final static String abc = null; //is discouraged and gives error. 
+1

你的问题是自相矛盾的,因此不清楚。它的一部分是关于“最终静态”成员初始化为“null”和初始化为其他值的问题之间的区别? –

+1

当你可以使用'null'时,为什么要用'null'初始化一个'final static'变量? –

+0

这似乎是两个问题之一。你应该分开它并提出第二个问题。 –

回答

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",这是有点冗长的整体呈现。它归结为原始类型或仅涉及整数文字,字符串文字,指定常量变量的名称以及相当大的Java运算符子集的表达式。这给我们带来了点:null既不是原始类型,也不String类型的,因此它不能出现在常量表达式,因此一个变量不是“恒定变量”,如果它有null或含有表达null作为它的初始值。这样一个变量,不是一个常量变量,不能出现在内部类中。

2

请阅读以下JLS section (§8.1.3)了解有关内部类中静态/非静态成员使用的规则。

内部类可以不声明静态初始化(§8.7)或构件 接口,或编译时会出现误差。

内部类可以不声明静态成员,除非它们是恒定 变量(§4.12.4),或发生编译时间错误。

注意上面的这一行 - “除非它们是常量变量”,它回答你的问题。当你声明一个原语或字符串为public static final时,它会变成一个“常量变量”,因此你可以在一个非静态的内部类中使用它,因为它不会破坏编译规则。

现在,为什么它不会中断编译规则,因为当你声明一个常量变量并初始化它时,编译器可以确定性地说这是这个变量的值,而如果你没有初始化它,那么编译器不能确定性地说这将是这个变量的值,并且不能确定它是否可以在运行时被修改,并且一旦它被赋值,你就不能改变最终值。在此JLS section (§4.12.4)

相关问题