zoukankan      html  css  js  c++  java
  • 第5条:避免创建不必要的对象

      一般来说,我们最好的做法是重用对象,而不是每次使用都new出一个新的相同功能的对象,这样做很高效,特别是对于那些不可变类来说。看一个极端的反面例子,如果String s = new String("stringette");每次都被执行的话都会创建一个新的实例,然而stringette本身就是String一个实例,功能和构造器创建的对象等,如果这种用法在一个for循环中,或者被频繁调用,那就会创造成千上万个String实例了。因此,使用 String s = "stringette"就不是每次执行的时候都创建一个新的实例,在同一台虚拟机中运行的代码,只要包含相同的字符串字面常量,该对象就会被重用。

      现在我们来看一个例子,比如有一个Person对象,对象中有一个字段是生日,生日是个常量,它不能被更改,现在需要完成一个方法,用这个方法我们可以获取到这个人是否出生在1946到1964年之间(也就是生育高峰期(baby boomer))

    public class Person {
            private final Date birthday;
            public Person(Date birthday) {
                this.birthday = birthday;
            }
    
            public boolean isBabyBoomer() {
                Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                //将时间设置为1946年1月1日0时0分0秒
                c.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
                Date boomStart = c.getTime();
                c.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
                Date boomEnd = c.getTime();
                return birthday.compareTo(boomStart) >= 0 && 
                                  birthday.compareTo(boomEnd) < 0;
            }
    }    

      从上面的isBabyBoomer可以看出,如果我们每次调用这个方法,都会新建一个Calendar、两个Date对象实例,这些都是不必要的,因而,我们现在对Person进行修改下已达到代码的重用。

    public class Person {
            private final Date birthday;
    
            private static final Date BOOM_START;
            private static final Date BOOM_END;
    
            public Person(Date birthday) {
                this.birthday = birthday;
            }
    
            static {
                Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                //将时间设置为1946年1月1日0时0分0秒
                c.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
                BOOM_START = c.getTime();
                c.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
                BOOM_END = c.getTime();
            }
    
            public boolean isBabyBoomer() {
                return birthday.compareTo(BOOM_START) >= 0 && 
                              birthday.compareTo(BOOM_END) < 0;
            }
    }

      好了,这样就很明显的可以看出,我们不需要每次都创建新的Calendar和Date对象实例了。

      建议:如果想要保证性能,则尽量使用基本数据类型而不是装箱基本类型,要当心无意识的自动装箱。如Integer k = 10;

      

      总结:本条的重点是避免创建多余的对象,提高重用性,但是需要注意对象的重用不能是盲目的,对于对象的重用,我们应该把目光集中在那些重量级的类,或是构造方法中需要做很多初始化的类的身上。对于一些比较轻量级的类,我们应该将代码的简洁和可维护性放在跟高的优先级上。

      

      

    作者:哀&RT
    出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    如何将一个类改造为线程安全
    50行代码实现缓存,JAVA内存模型原理
    Qt 解压/压缩文件
    QT学习笔记—1
    在http编程的门口飞牛网自动下单,查单
    QList 排序
    Qt 打开指定的文件
    spoj 375 query on a tree 题解
    uva 11388 GCD LCM题解
    uva 1476 Error Curves 题解
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6695145.html
Copyright © 2011-2022 走看看