`
aqxyjay
  • 浏览: 3796 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

EJ.05 避免创建不必要的对象

    博客分类:
  • EJ
 
阅读更多
  • 重用对象而不是每次都创建一个相同功能的对象

极端的反面例子,每次执行都会创建一个新的String实例:

 

String s = new String("stringette");  // DON'T DO THIS!

 建议:

String s = "stringette";

 

 

  • 不可变类通常可以使用静态工厂方法来避免创建不必要的对象
遗留任务:
  1. Boolean.valueOf(String)总是优先于构造器Boolean(String),确认valueOf的实现;
  2. Boolean b = true,确认语句的实现,是否会创建对象。
  • 重用那些已知不会被修改的可变对象
反面的例子,方法每次调用都会创建一个Calendar、一个TimeZone和两个Date对象:
public class Person {
    private final Date birthDate;
    
    // Other fields, methods, and constructor omitted
    // DON'T DO THIS!
    public boolean isBabaBoomer() {
        // Unnecessary allocation of expensive object
        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;
    }
}
 建议:
public class Person {
    private final Date birthDate;
    // Other fields, methods, and constructor omitted
    /**
     * The starting and ending dates of the baby boom
     */
    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 isBabaBoomer() {
        return birthDate.compareTo(BOOM_START) >= 0
                && birthDate.compareTo(BOOM_END) < 0;
    }
}
 
  • 针对某个特定对象的特定适配器情形,不需要创建多个适配器实例(见EJ p19例,Map接口的keySet方法)
  • 注意自动装箱,优先使用基本类型,当心无意识的自动装箱

 

    // Hideously slow program! Can you spot the object creation?
    public static void main(String[] args) {
        Long sum = 0L;
        for (long i = 0; i < Integer.MAX_VALUE; i++) {
            sum += i;
        }
        System.out.println(sum);
    }

 遗留任务:学习自动装箱。

 

 

  • 小对象的创建和回收动作是非常廉价的
  • 非常重量级的对象可以使用对象池(object pool),如数据库连接
遗留任务:
        学习EJ.39时,注意“保护性拷贝(defensive copying)”的内容,并总结两者的区别。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics