其实这一条的题目应该再多几个字“在四中嵌套类中,优先考虑静态成员类”,这样才更不容易产生歧义。
所谓嵌套类(nested class)是指定义在另一个类内部的类。嵌套类存在的目的应该只是为了它的外围类提供服务。共分为四种:
1)静态成员类(static member class)
2)非静态成员类(nonstatic member class)
3)匿名类(anonymous class)
4)局部类(local class)
其中后三者又被统称为内部类(inner class)
本条就是说在以上这四中,应该优先使用静态成员类。它是一种最简单的嵌套类。最好把它看成是一个普通的类,只是恰好被声明在了另一个类的内部而已,它可以访问外围类的所有成员(包括private)。
静态成员类的一种通常用法是作为公有的辅助类,仅当与它的外部类一起使用时才有意义。
如:一类汽车,它们有各种不同的档位,那么描述这些档位的枚举常量,应该是 MotorCar.TapPosition.TAP_ONE 和 MotorCar.TapPosition.TAP_TWO 等等的。 这里的TapPosition就是MotorCar的静态成员类。脱离开MotorCar,你是无法直接使用TapPosition的(也没有意义)。
非静态成员类从语法的角度仅与静态成员类有一子之差——修饰符中不含static。尽管它们的语法非常相似,但用处有很大不同。非静态成员类得每一个实例都隐含着与外围类的一个外围实例紧密关联在一起,在其内部调用外围类的方法是可能的,也可以使用this引用。(更多关于非静态成员类使用方法的介绍,可以搜索Adaper 适配器,或参考Map、Set、List的各种实现类)
换言之,一个嵌套类是否可以在它的外围类的实例之外独立存在,是决定使用静态成员类还是非静态成员类的一个重要依据。
匿名类不同于Java语言中的任何其他语法单元,它是没有名字的。它不是外围类的一个成员。它并不与其他成员一起被声明,而是在被使用的点上,同时被声明和实例化。因此匿名类只能被用在代码中它将被实例化的那个点上。还有,因为它没有名字,所以在它被实例化后就不能再对它进行引用。
匿名类出现在表达式中间,所以它们应该非常简短,太长的话影响可读性。匿名类的通常用法是:
1)创建一个函数对象
Arrays.sort(args, new Compartor() {
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length();
}
});
2)创建一个过程对象
最后说局部类,局部类是四种嵌套类中最少使用的类。在任何“可以声明局部变量”的地方,都可以声明局部类,它也遵循着同样的作用域规则。局部类与其他三种嵌套类的每一种都有一些共性。
总之,四种嵌套类,各有各的用处。如果一个嵌套类需要在一个以上的地方使用,或者它太长了,不适合放在一个方法(注意:不是类)内部,那么应该使用成员类。如果成员类的每个实例都需要一个指向外围实例的应用(需要使用this),则他成员类做成非静态的;否则就应该做成静态的。
【Effective Java 学习笔记】系列连载专题请见:
http://tonylian.iteye.com/categories/64208