一.重用不可变的对象
1.String str="Are You ok?"; //而不是String str=new String("Are You ok?");
如果字符串的内容不变且该对象需要被多次使用,那么可以使用上面推荐的创建字符串的方式将其放于常量池中(常量池简介)。它可以保证,对于所有在同一虚拟机中运行的代码,只要它们包含相同的字符串字面常量,该对象就会被重用。String str=new String(“Are You ok?”)的创建方式会使每次运行到该句代码(循环或者被多次调用的函数等等)就会重新创建一个String对象。
2.Boolean isSuccess=Boolean.valueOf("true"); //而不是Boolean isSuccess= new Boolean("true");
推荐方法使用Boolean的静态成员函数获取它的常量成员Boolean.FALSE或Boolean.TRUE,这样即使你使用了N个Boolean变量,它们依然指向了Boolean类里面仅有的两个声明的常量。
Boolean isSuccess= new Boolean(“true”);每次调用该句代码都会创建一个Boolean对象。
静态工厂方法(通过调用该类的静态方法返回一个该类的对象)大多数情况下优于构造器方法
//JDK1.8中的Boolean类的源码
public static final Boolean TRUE = new Boolean(true);//常量,初始化一次
public static Boolean valueOf(String s) {//Java源码
return parseBoolean(s) ? TRUE : FALSE;
}
PS:既然静态工厂方法同一个值返回的是同一个对象,那么下列判断的结果就会是如此。(Integer类会将会缓存-128—-127之间的数值)
Integer integer1=Integer.valueOf(1);
Integer integer2=Integer.valueOf(1); //==是对象引用的比较
System.out.println(integer1==integer2); //true
integer1=new Integer(1);
integer2=new Integer(1);
System.out.println(integer1==integer2); //false
//JDK1.8中的Integer类的源码
public static Integer valueOf(int i) { //low=-128,high=127
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); //static final Integer cache[];
}
二.重用已知不会被修改的对象
1.善用静态成员变量和常量减少对象的创建
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate=birthDate;
}
//将不会改变的对象声明为静态变量,仅初始化一次而不是声明为函数中的局部变量,那样
//每一次函数的调用都伴随这种不需要改变的对象的重复创建
private static final Date BOOM_START;
private static final Date BOOM_END;
//应用启动即被初始化,可以使用延迟初始化使isBabyBoomer方法被调用的时候才初
//始化这些变量
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;
}
}
三.避免无谓的装箱/拆箱操作
1.优先使用基本数据类型,而不是装箱基本类型,当心无意识的自动装箱。
public static void main(String []args){
Long sum=0L;
for(long i=0; i<Integer.MAX_VALUE;i++){
sum+=i;//由于sum为Long类型,每次都会对i进行装箱操作
}
System.out.printLn(sum);
}
参考资料:
《Effective Java》