《Effective Java》之避免创建不必要的对象

一.重用不可变的对象

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》

猜你喜欢

转载自blog.csdn.net/qq_32483145/article/details/79769464