概述
一、引子
一般来说,最好能重用对象而不是每次需要的时候就创建一个相同功能的新对象,特别是当对象不可变时,它始终可以被重用的。重用对象对程序性能起到重要作用。
二、重用不可变对象
对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。
Boolean b1 = Boolean.valueOf("test"); // 使用静态工厂方法(good)
Boolean b2 = new Boolean("test"); // 使用构造器(bad)
三、重用不会被修改的可变对象
下面的例子业务为:检验某个人是否出生于1946年 ~ 1964年期间。
/*
* 改进前
*/
public class Person {
private Date birthDate = new Date();
public boolean isBabyBoomer() {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = calendar.getTime();
calendar.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = calendar.getTime();
return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0;
}
}
/*
* 改进后
*/
public class Person2 {
private Date birthDate = new Date();
private static Date BOOM_START;
private static Date BOOM_END;
static {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = calendar.getTime();
calendar.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = calendar.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0;
}
}
改进前每调用一次isBabyBoomer都会创建一个Calendar,TimeZone,Date对象,改进后的程序只会在初始化的时候创建这些对象一次。如果isBabyBoomer方法被频繁的调用,那么将会显著地提高性能。
四、自动装箱和拆箱
看一下下面这个小程序,不知道你能不能发现什么问题?
public class Client {
public static void main(String[] args) {
long start = System.currentTimeMillis();
Long sum = 0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println(">>>>>>>>>>Total spent time: " + (end - start) / 1000 + "s");
}
}
因为sum定义为Long类型,导致这个程序创建了很多不必要的对象,每次往Long sum中增加long i 时都会构建一个实例。
结论:要优先使用基本数据类型而不是装箱基本类型,要当心无意识的自动装箱。
最后
以上就是缓慢纸飞机为你收集整理的Effective Java (5) - 避免创建不必要的对象的全部内容,希望文章能够帮你解决Effective Java (5) - 避免创建不必要的对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复