您的位置:首页 > 其它

第5条:避免创建不必要的对象

2017-03-13 19:07 211 查看

第5条:避免创建不必要的对象

简而言之,就是说最好能够重用对象而不是每一次都创建一个新的。

下面就是一个反面的例子:

String s = new String("stringtte");


每次执行这条语句时都会创建一个新的实例。而且其中的“Stringtte”参数本身就是一个String的实例,这就相当于这一条语句中同一个实例创建了两次。

而通常的写法是这样:

String s = "stringette";


这种写法可以保证包含相同字符串常量的String对象均会被重用。

可以通过使用静态工厂方法来避免重复创建对象。

首先是反例代码:

public class Person {
private final Date birthDate;

public boolean isBabyBoomer() {
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;
}
}


当isBabyBoomer方法每一次被调用时,都会新建一个Calendar,一个TimeZone和两个Date对象,如果调用这个方法非常频繁,那么会很明显地拖慢执行速度。

而合适的做法是将boomStart与boomEnd作为常量,只在初始化时赋值一次:

class Person {
private final Date birthDate;

private static final Date BOOM_START;
private static final Date BOOM_END;

static {
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
4000
boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >=0 && birthDate.compareTo(BOOM_END) < 0;
}


还有一种更加优化的方法,因为如果Person类被实例化,但是isBabyBoomer方法并没有被调用,那么可以在第一次调用isBabyBoomer方法时再为两个常量赋值,但是书中不建议这么做,因为这样对性能的提升并不大,却会导致逻辑更加混乱。

还有值得注意的一点,在Java 1.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);
}


这段代码输出是正确的,但是因为第2行中使用的是Long而不是long,会导致运行时生成大量多余的对象,极大地影响的运行效率。所以要优先使用基本类型而不是包装类,要当心无意识的自动装箱
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: