美文网首页
5.避免创建不必要的对象

5.避免创建不必要的对象

作者: 陈继科 | 来源:发表于2016-08-29 15:29 被阅读70次

最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。

如果对象是不可变(immutable),它就始终可以被重用

String s = new String("stringette");

每次执行上面的语句都会创建一个新的String实例。因为"stringette"本身就是一个String实例,这和构造器创建出来的新对象功能方面完全相同。如果频繁调用这一方法,就会创建成千上万不必要的String实例。

String s = "stringette";

这样就保证了只有一个String实例,而不是每次执行都创建一个新的实例。并且同一台JVM只要字符串字面常量相同,对象就会被重用。
同时提供静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器以避免创建不必要对象。例如静态工厂方法Boolean.valueOf(String)回返回一个固定的Boolean实例,而构造器Boolean(String)在每次被调用都会创建一个新的对象。

已知可变对象不会被修改,则也可以重用

public class Person {
    private final Date birthDate;

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    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 birthDate.compareTo(boomStart)>=0&&birthDate.compareTo(boomEnd)<0;
    }
}

这个类问题在于当isBabyBoomer每次被调用的时候,都会创建一个Calendar、一个TimeZone和两个Date实例,这是不必要的。下面用静态初始化器(initializer),避免这种效率低下情况:

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

这样Person类只在初始化时创建Calendar、TimeZone和Date实例一次,而不是每次调用isBabyBoomer的时候都创建这些实例。除了性能的提升,代码的含义也更加清晰——boomStart和boomEnd从局部变量改为final静态域,表明这些数据被当成常量对待,使得代码更易于理解。

自动装箱、拆箱可能会创建多余对象。

public static void main(String[] args){
        Long sum=0L;
        for(long i = 0; i< Integer.MAX_VALUE; i++){
                sum+=i;
        }
}

sum被声明为Long而不是long,这样程序构造了2^31个多余的Long实例。所以这里结论是要优先使用基本类型而不是装箱类型,当心无意识自动装箱。

注意

不要认为“创建对象代价非常昂贵”。实际上小对象的构造器只做很少量的显式工作,所以小对象的创建和回收动作是非常廉价的,现代JVM上更是如此。通过创建附加的对象,提升程序的清晰性、简洁性和功能性。
反之自己维护对象池很麻烦,除非对象非常重量级,比如数据库连接池

相关文章

  • 5.避免创建不必要的对象

    一般来说,如果能重用对象,尽量重用对象,而不是创建一个相同的对象.如果对象是不可变的,它始终就应该被重用. 作者举...

  • 5.避免创建不必要的对象

    最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。 如果对象是不可变(immutable),它就始终...

  • 条目6:避免创建不必要的对象

    避免创建不必要的对象 避免通过构造函数创建字符串 避免使用String.match方法做正则匹配 避免在循环中频繁...

  • 避免创建不必要的对象

    在编码中尽量减少大对象的使用,创建对象的成本是非常高的。举个栗子: 代码块一 代码块二 在代码块一中我们使用的是l...

  • 避免创建不必要的对象

    第五条:避免创建不必要的对象 1. 简介 一般来说,我们最好的做法是重用对象,而不是每次使用都new出一个新的相同...

  • 避免创建不必要的对象

    一般来说,最好能重用对象而不是每次需要的时候就创建一个相同的对象。如果对象是不可变的,它就始终可以被重用。 例子:...

  • 避免创建不必要的对象

    记住一个原则:能重用对象就不要每次都创建一个新的对象。例一: 字符串常量在JVM常量池中储存。 例二:对于同时提供...

  • 避免创建不必要的对象

    一、错误做法 二、正确做法

  • Android 如何提高代码质量?

    避免创建不必要的对象,尽可能避免频繁的创建临时对象,例如在for循环内,减少GC的次数。 尽量使用基本数据类型代替...

  • GeekBand C++设计模式

    5.对象创建 通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持...

网友评论

      本文标题:5.避免创建不必要的对象

      本文链接:https://www.haomeiwen.com/subject/enlosttx.html