【读书笔记 - Effective Java】05. 避免建立没必要要的对象

1. 若是对象是不可变的(immutable),它就始终能够被重用。java

(1) 特别是String类型的对象。数据库

String str1 = new String("str"); // 建立许多没必要要的实例
String str2 = "str"; // "str"其自己是一个String实例,对于全部同一台虚拟机中运行的代码,只要它们包含相同的字符串字面常量,该对象就会被重用

(2) 同时提供了静态工厂方法和构造器的不可变类,一般可使用静态工厂方法而不是构造器。安全

2. 若是可变对象是已知不会被修改的,它也能够被重用。性能

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class Person {
    private final Date birthday;
    // ...
    
    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 birthday.compareTo(boomStart) >= 0 &&
                birthday.compareTo(boomEnd) < 0;
    }
}

若是isBabyBoomer()常常被调用,那么每一次都要建立Calendar,Date的实例,效率低下。如下方式提升了性能,代码含义也更加的清晰。spa

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class Person {
    private final Date birthday;
    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 birthday.compareTo(BOOM_START) >= 0 &&
                birthday.compareTo(BOOM_END) < 0;
    }
}

 

建立多余对象的新方法:自动装箱(autoboxing)。但要优先使用基本类型而不是装箱基本类型,要小心无心识的自动装箱,否则会建立多个多余的实例。code

 

(与第39条呼应)因重用对象而付出的代价要远远大于因建立重复对象而付出的代价时,提倡使用保护性拷贝对象

好比除非池中的对象是很是重量级的(数据库链接池),不然不要维护本身的对象池(object pool)。通常维护本身的对象池一定会把代码弄的很乱,同时增长内存占用,而且还会损害性能。blog

必要时候没实施保护性拷贝,会致使潜在的错误和安全漏洞内存

没必要要的建立对象,会影响程序的风格和性能
字符串

相关文章
相关标签/搜索