读书笔记 仅供参考
方法一
使用静态工厂方法
方法二
使用不可变对象,例如 String
正确使用
String s = "stringette";
错误使用
String s = new String("stringette");
后者会每次调用都创建一个 String 对象,前者则是从常量池中取出相同的对象。
方法三
重用已知不会被修改的对象
错误例子
//判断一个人是否在 1946-1964 年间出身
public class Person {
private final Date birthData;
public boolean isBabyBoomer() {
Calendar gmtCal =
Calendar.getinstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = getCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = getCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
上面的例子每次被调用都会创建一个 Calendar,一个 TimeZone 和两个 Date 实例。
正确的例子
public class Person {
private final Date birthData;
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 = getCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = getCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
自动装箱
Java 1.5 后,出现自动装箱,会创建多余的对象,基本类型和装箱基本类型的性能上有明显的差别。
所以:要优先使用基本类型而不是装箱基本类型,当下无意识的自动装箱。
PS
本条目并不意味着创建对象的代价很昂贵,小对象的创建和回收动作非常廉价。维护对象池来避免创建对象并不是很好的做法,除非对象池中的对象非常重量级,例如数据库连接池。