Effective-Java-24静态成员类优于非静态成员类

本条目将告诉你什么时候应该使用哪种嵌套类,以及这样做的原因。

嵌套类(nested class)是指定义在另一个类内部的类。嵌套类存在的目的应该只是为他的外围类(enclosing class)提供服务。如果嵌套类将来可能会用于其他的某个环境中,它就应该是顶层类(top-level class)。[1]
嵌套类有四种:

  1. 静态成员类 (static member class)

  2. 非静态成员类 (nonstatic member class)

  3. 匿名类 (anonymous class)

  4. 局部类 (local class)

除了第一种之外,其他三种都称为内部类(inner class)[2]

静态成员类是最简单的一种嵌套类。最好把他看作是普通类,只是被声明在另一个类的内部而已,它可以访问外围类的所有成员,包括那些声明为私有的成员[3]静态成员类是外围类的一个静态成员,与其静态成员一样,也遵守同样的可访问性规则。如果他被声明为私有的,它就只能在外围类的内部才可以被访问,等等。[4]

静态成员类的一种常见用法是作为共有的辅助类,只有与它的外部类一起使用才有意义。例如,以枚举为例,它描述了计算器支持的各种操作(第34条)。Operation枚举应该是Calculator类的公有静态成员类,之后Calculator类的客户端就可以用诸如Calculator.Operation.PLUS 和 Calculator.Operation.MINUS 这样的名称来引用这些操作。[5]

从语法上讲,静态成员类和非静态成员类之间唯一的区别是,静态成员类的声明中包含修饰符static。尽管它们的语法非常相似,但是这两种嵌套类有很大的不同。[6]非静态成员类的每个实例都隐含地与外围类的一个外围实例(enclosing instance)相关联。[7]在非静态成员类的实例方法内部,可以调用外围实例上的方法,或者利用修饰过的this (qualified this) 构造获得外围实例的引用[JLS, 15.8.4]。[8]如果嵌套类的实例可以在它外围类的实例之外独立存在,这个类就必须是静态成员类:在没有外围实例的情况下,要想创建非静态成员类的实例是不可能的。[9]


  1. Joshua Bloch, Effective Java, 3rd Edition, Item 24, gives the design rule that nested classes should serve their enclosing class; Java Language Specification SE 21, §8.1 Class Declarations, defines where class declarations may appear. ↩︎

  2. Oracle Java Tutorials, Nested Classes, distinguishes static nested classes from inner classes; JLS SE 21, §8.1.3 Inner Classes and Enclosing Instances, defines inner classes as nested classes that are not explicitly or implicitly static. ↩︎

  3. Oracle Java Tutorials, Nested Classes, describes static nested classes as members of the enclosing class and notes their access relationship with the enclosing class members. ↩︎

  4. JLS SE 21, §8.5 Member Type Declarations, treats member classes and interfaces as class members; the usual member access-control rules apply to their declarations. ↩︎

  5. Effective Java Item 24 uses public static member classes as helper types whose names and meaning are tied to the enclosing type. ↩︎

  6. Oracle Java Tutorials, Nested Classes, explains the terminology distinction between static nested classes and inner classes. ↩︎

  7. JLS SE 21, §8.1.3 Inner Classes and Enclosing Instances, specifies the relationship between inner class instances and enclosing instances. ↩︎

  8. JLS SE 21, §15.8.4 Qualified this, defines qualified this expressions used to refer to lexically enclosing class instances. ↩︎

  9. Effective Java Item 24 draws the practice conclusion: if a member class does not require an enclosing instance, make it static; this follows from the enclosing-instance rules in JLS §8.1.3. ↩︎