通过私有构造器枪花不可实例化的能力
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for nonintantiability
private UtilityClass() {
throw new AssertionError();
}
... // Remainder omitted
}
- 显示的构造器是私有的,不可以在类的外部访问。
- AssertionError()不是必需的,但是可以避免无意中在类的内部访问。
- 注释可以帮助理解将构造函数设置成私有的原因。
私有的显示构造器将导致一个类不能被子类化。因为所有的构造器都必须显示或隐式的调用超类的构造器。
避免创建不必要的对象
class Person {
private final Date brithDate;
// Other fields, methods, and constructor omitted
// The starting and ending dates of the baby boom.
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer(){
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
消除过期的对象引用
内存泄露的常见来源:
- 自己管理内存。
- 缓存
- 监听器和其他回调
避免使用终结方法
终结方法(finalizer):
- 不保证会被及时地执行
- 不保证被执行
当类的对象中封装的资源确实需要终止,可以提供一个现实的终止方法,并要求改类的客户端在每个实例不再有用的时候调用这个方法。
显示的终止方法通常与try-finally结构结合起来使用,以确保及时终止。
// try-finally block guarentees execution of termination methods
Foo foo = new Foo(...);
try{
// Do what must be done with foo
...
} finally {
foo.terminate(); // Explicit termination method
}
终结方法的两种用途:
- 当对象的所有者忘记调用显示终止方法时,终结方法可以充当“安全网”。
- 与native peer有关。
终结方法链:如果类有终结方法,并且子类覆盖了终结方法,子类的终结方法就必须手工调用超类的终结方法。
@Override protected void finalize() throws Throwable {
try{
... // Finalize subclass state
} finally {
super.finalize();
}
}