该知识点是自己从书籍中学习的笔记。
1.重复使用同一对象比每次创建与该对象功能一样的新对象好。重复使用对象效率更快、更优雅。如果一个对象是一直不变的话,最好是重复使用。
比如下面的使用就不太好:
String s = new String(“Hello”);//不太好,每次都会创建新的String对象,而该对象是不需要的。
可以替换成:String s = “Hello”;//在同一个jvm中,“Hello”会保存在String池中,在堆中不会生成新的对象。
2.为了避免创建不必要的对象,你可以使用静态工厂方法和构造方法(前者性能较后者好,因为后者始终会创建一个新对象)。但是在实际运作中,并不用静态工厂方法。
3.除了重复利用一层不变的对象,创建好的并且对象的设置不会被修改的可变对象也是可以重用的。例子1:
class TEST {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
// Other fields, methods, and constructor omitted
// DON'T DO THIS!
public boolean isBabyBoomer() {
// Unnecessary allocation of expensive object
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0
&& birthDate.compareTo(boomEnd) < 0;
}
}
例子2:
class TEST1 {
private final Date birthDate;
// 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 Person1(Date birthDate) {
this.birthDate = birthDate;
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0
&& birthDate.compareTo(BOOM_END) < 0;
}
}
明显例子2比例子1好,因为比较的时间不会每次都生成。
4.从jdk1.5开始,要优先考虑原生态的数据类型。下面的例子说明自动装箱后的速度比原生态慢:
public static void main(String[] args) {
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
因为sum是Long对象的,要装箱2的31次。如果将Long修改成long,就快了。
5.如果类的构造方法本身就小,就不太推荐使用对象池的方法来管理已存在的对象。因为编写对象池会增加代码难度,比直接建立新对象的花销更大。
使用对象池较好的一个例子就是数据库的链接池,因为链接数据库本身的花销就大,所以建立一个链接池存放已经有的对象就比较好。但是对于较小的类的构造方法的话,还是使用直接创建对象较好。
6.当然并不是重用已有的对象就是比较完美的,当在保护性拷贝(defensive copying)的场合时,就比重复使用对象较好。在保护性拷贝的情况下没有使用保护性拷贝的话,会导致潜在的错误和安全漏洞;而使用重复的对象仅仅是在性能和风格上有问题而已,其风险不高。