一般情况下,最好重用功能上对等的对象,而不是创建新的对象。重用对象可以提高性能,并且样式良好。如果对象是immutable的(private fields, no setter methods),那么重用起来就比较方便。
不良例子:
String name = new String(“HelloWorld”);
每次执行时,都会创建一个新的String对象。其中构造方法的参数本身就是一个对象,这样的构造方法没有必要,如果这样的语句出现在循环中,将会导致非常多的不必要的对象的创建。
修正:
String name = “HelloWorld”;
该语句创建了单一的对象。这个对象还可以被之后运行在同一个虚拟机总的其他使用相同字符串的代码重用。
package com.googlecode.javatips4u.effectivejava.unnecessary;
public class UnnecessaryObjectsSample {
public static void main(String[] args) {
long nanoTime = System.nanoTime();
String name = null;
for (int i = 0; i < 10000; i++) {
// DO NOT DO THIS
name = new String("name");
}
System.out.println(System.nanoTime() - nanoTime);// 2262299
nanoTime = System.nanoTime();
for (int i = 0; i < 10000; i++) {
// CHANGE TO THIS
name = "name";
}
System.out.println(System.nanoTime() - nanoTime);// 867987
System.out.println(name);
}
}
可以使用工厂方法来避免创建不必要的对象。
package com.googlecode.javatips4u.effectivejava.unnecessary;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class BadMutableObjectUsage {
private final Date birthDate = null;
// DON'T DO THIS!
public boolean isBabyBoomer() {
// Unnecessary allocation of expensive object
// Here the two Date objects are immutable.
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;
}
}
上面例子中两个Date对象,即开始时间和结束时间是常量,所以不需要在isBabyBoomer方法中每次被调用时都进行创建,而应该作为类的静态变量进行static初始化。
责任编辑:cyth