TIP21.用函数对象表示策略
如果一个类仅仅导出一个方法,而这个方法执行其它对象上的操作,那么这个类的实例实际上等同于一个指向该方法的指针。这样的实例被成为函数对象。
函数指针的主要用途就是实现策略模式。通常用匿名类声明并实现一个具体的策略类,如果这个策略类是设计用来重复使用的,通常就应该被实现为私有的静态类以便重复使用。
具体请参考java.util中的Comparator接口,以及容器类中的排序策略实现。
TIP22.优先考虑静态成员类
4种嵌套类
- 静态成员类 static member class 普通的类,碰巧被声明在另一个类的内部而已。
可以访问外围类的所有成员。
是外围类的一个静态成员,也遵守同样的访问规则。 - 非静态成员类 nonstatic member class
每个非静态成员类的实例,都隐含着与外围类的一个外围实例相关联。
常见用法是定义Adapter,以及集合接口的迭代器。 - 匿名类 anonymous class 常用于动态的创建函数对象。
- 局部类 local class 用的很少。
如果声明成员类不需要访问外围实例,就应使用static声明。如果省略static,每个实例都将包含一个额外的指向外围对象的引用,增加不必要的开销,并且会导致外围实例在符合垃圾回收时,仍然得以保存。
TIP23.请不要在代码中使用原生态类型
泛型
声明中具有一个或多个类型参数(Type Parameter)的类或接口,就是泛型类或者接口。
原生态类型
每个泛型都定义一个原生态类型(raw type),即不带任何实际类型参数的泛型名称。例如,List的原生态类型就是List。很明显,它是类型不安全的。
原生态类型的问题在于,失去了泛型安全性和表述性方面的所有优势。
如果不确定或不关心实际的类型参数,请用?代替,这被称为无限制的通配符类型。
例外
基于泛型信息可以在运行时被擦除的事实,有两条例外。
- 在类文字(class literal)中必须使用原生态类型。比如List.class合法,而List.class不合法。
- 使用instanceof操作符时,使用参数化类型是非法的。而且用?代替原生态类型,对操作符的行为不会产生任何影响,它们是多余的。