Java中普通内部类为何不能有static数据和static字段,也不能包含嵌套类。


普通内部类不能有static的字段与方法,这个规定大家都知道,可是原因是什么呢?
Thinking in Java的内部类章节对此的解释:
“普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含所有这些东西。”
后来我又看了下英文版的原文:
Fields and methods in ordinary inner classes can only be at the outer level of a class, so ordinary inner classes cannot have static data, static fields, or nested classes. However, nested classes can have all of these.
按字面意思看翻译的差不多,可是不理解其中的原由,希望明白人给解释一下,或者阐述您对这个规定的理解。

java jvm

蓝蓝露D轨迹 11 years, 10 months ago

TIJ, Effective Java, SOF.. 找了一圈都没有看到让我满意的答案.

Oracle官方文档
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html:
"Also, because an inner class is associated with an instance, it cannot define any static members itself."

我想了挺久, 我下面给出来的代码还是可以解释原因的:

   
  public class Outter {
  
class Inner{
private final static int x=1;
/* compile errors for below declaration
* "The field x cannot be declared static in a non-static inner type,
* unless initialized with a constant expression"*/
// final static Inner a=new Inner();
// static Inner a1=new Inner();
// static int y;
}
}

如果上面的代码编译无误, 我们可以直接 Outter.Inner.a来拿到Inner类的实例, 而内部类的实例是一定要绑定到一个外部类的实例的.

更新

补充一下, 实际上非static内部类里, static数据成员不是加了final的变量就可以了

比如:

   
  public class Outter {
  
class Inner{
final static Date t=new Date();
}
}

用jdk1.7的javac, 可以看到这个:

   
  Outter.java:7: 错误: 内部类Outter.Inner中的静态声明非法
  
final static Date t=new Date();;
^
修饰符 'static' 仅允许在常量变量声明中使用

明显是不对的, 这里我们确实给了一个 "常量变量声明"了(final).

java在这上面有bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=343480

如果在新版的eclipse上, 可以看到:
The field t cannot be declared static in a non-static inner type, unless initialized with a constant expression
不仅需要final, 还需要初始化为一个常量表达式.

darling answered 11 years, 10 months ago

Your Answer