一般来说,对于能够重用的对象,而不是在每次需要的时候就创建一个相同功能的新对象。重用的方式即快速,又流行。如果对象是不可变,他就始终可以被重用。
String s=new String("person");
该语句每次被执行时都会创建一个String实例,对于这些创建的动作完全是不必要的。传递给String构造器的参数,本身就是String实例,功能方面等同于构造器创建的所有对象。
改进后版本如下。
String s="person";
这个版本只用了一个String实例,而不是每次执行都会创建一个新的实例。对于所有在同一台虚拟机运行的代码,只要他们包含相同的字符串字面常量,就会被重用。
对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。构造器每次在被调用时都会创建一个新的对象,而静态工厂方法则从来不要求这么做,实际上也不会这样做。
除了重用不可变的对象之外,也可以重用那些已经不会被修改的可变对象。
这个类建立了一个模型,用于检验一个人是否在1946到1964年出生
import java.util.*;
public class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = new Date(birthDate.getTime());
}
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实例。这是不必要的,下面的版本就是用静态域的初始化,避免效率这种效率低下的情况。
import java.util.*;
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = new Date(birthDate.getTime());
}
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 boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
改进后的person类,只在初始化时创建Calendar,TimeZone和Date实例一次,而不是在每次调用isBabyBoomer()的时候创建这些实例。如果频繁的调用isBabyBoomer(),那么性能将显著的提高。
在Java1.5发行版本中,有一种创建多余对象的新方法,称作自动装箱。
public class Sum {
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的31次方的Long实例,将sum的声明改成long,速度提升约7倍。
结论很明显,要优先使用基本类型。
最后
以上就是安详宝贝最近收集整理的关于Effective Jave 创建和销毁对象 5.避免创建不必要的对象的全部内容,更多相关Effective内容请搜索靠谱客的其他文章。
发表评论 取消回复