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轨迹 10 years, 9 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 10 years, 9 months ago

Your Answer