学习effective java-5创建和销毁对象之避免创建不必要的对象

该知识点是自己从书籍中学习的笔记。

  1.重复使用同一对象比每次创建与该对象功能一样的新对象好。重复使用对象效率更快、更优雅。如果一个对象是一直不变的话,最好是重复使用。

  比如下面的使用就不太好:

   String s = new String(“Hello”);//不太好,每次都会创建新的String对象,而该对象是不需要的。

  可以替换成:String s = “Hello”;//在同一个jvm中,“Hello”会保存在String池中,在堆中不会生成新的对象。

  2.为了避免创建不必要的对象,你可以使用静态工厂方法和构造方法(前者性能较后者好,因为后者始终会创建一个新对象)。但是在实际运作中,并不用静态工厂方法。

  3.除了重复利用一层不变的对象,创建好的并且对象的设置不会被修改的可变对象也是可以重用的。例子1:

class TEST {

    private final Date birthDate;

 

    public Person(Date birthDate) {

       this.birthDate = birthDate;

    }

 

    // Other fields, methods, and constructor omitted

    // DON'T DO THIS!

    public boolean isBabyBoomer() {

       // 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;

    }

}

例子2:

class TEST1 {

    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 Person1(Date birthDate) {

       this.birthDate = birthDate;

    }

 

    public boolean isBabyBoomer() {

       return birthDate.compareTo(BOOM_START) >= 0

              && birthDate.compareTo(BOOM_END) < 0;

    }

}

明显例子2比例子1好,因为比较的时间不会每次都生成。

4.从jdk1.5开始,要优先考虑原生态的数据类型。下面的例子说明自动装箱后的速度比原生态慢:

    public static void main(String[] args) {

       Long sum = 0L;

       for (long i = 0; i < Integer.MAX_VALUE; i++) {

       sum += i;

       }

       System.out.println(sum);

  }

因为sum是Long对象的,要装箱2的31次。如果将Long修改成long,就快了。

5.如果类的构造方法本身就小,就不太推荐使用对象池的方法来管理已存在的对象。因为编写对象池会增加代码难度,比直接建立新对象的花销更大。

使用对象池较好的一个例子就是数据库的链接池,因为链接数据库本身的花销就大,所以建立一个链接池存放已经有的对象就比较好。但是对于较小的类的构造方法的话,还是使用直接创建对象较好。

6.当然并不是重用已有的对象就是比较完美的,当在保护性拷贝(defensive copying)的场合时,就比重复使用对象较好。在保护性拷贝的情况下没有使用保护性拷贝的话,会导致潜在的错误和安全漏洞;而使用重复的对象仅仅是在性能和风格上有问题而已,其风险不高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值