Effective Java读书笔记四

来源:互联网 发布:date转json 编辑:程序博客网 时间:2024/05/16 09:12

      

Item5:避免创建不需要得对象

在很多时候我们可以重用已有的对象而不需要创建新的对象,尤其这个对象是immutable的。比如String类型的对象,我们一般不会这么用:

 

因为这种做法每次都会创建一个新的String对象,对性能是一种损耗,而String是一个immutable的类型。

当一个immutable类既提供了构造函数,又提供了static factory methods的时候,我们首先考虑使用static factory methods,比如Boolean类,它的valueOf方法返回的是可重用Boolean.TRUE或者Boolean.FALSE,而构造函数每次都会创建一个新的Boolean对象。

另外,当我们确定一个mutable的对象不会被修改时,也可以重用这个对象。比如Date对象。Joshua在书中用Calendar来做例子,大多数情况下Calendar对象创建后是可以重用的,而Calendar是一个很笨重的类,所以如果需要,不要把它放到方法的局部变量中去。Joshua用局部变量的版本和类变量的版本各运行1千万次来做比较,后者较前者快了250倍。

adapters(设计模式)创建之后,因为它内部不会保存状态,所以这样的对象也是可以重用的。例如Map中的keySet方法会返回一个Set对象,这个对象就是adapters模式中的view,它的方法仅仅将调用请求委派给Map对象内部。

从Java 5.0之后还需要注意一个创建不必要对象的地方,那就是autoboxing。对比以下的两个版本:

 

当我们将sum类型从Long变为long后,执行这段代码的时间从43秒降到了6.8秒。因为在计算的过程中,Version A从0到Integer.Max_Value(也就是231)的循环中,每次都要创建一个Long的对象(实际上并不是,下面解释),这样就大概创建了231个Long的对象,显然这是一种浪费。所以在编写程序的过程中,我们首先考虑int,long,double等基本型。

最后,Joshua建议不要对象池来管理对象,除非不得已,比如对象很大,典型的有数据库的连接等。创建自己的对象池会弄乱代码,增加内存的占用,损害性能。而现在的JVM能够很好的管理轻量级的对象。

不过需要注意的是,不能一味的追求重用对象,因为这样可能会带来潜在的bug或者安全漏洞。

最后说一下autoboxing的问题,并不是每一次从基本型到对象型的转换都会创建新的对象。Java为每一个基本型所对应的对象类型都事先创建了一部分static的对象。对于这部分的autoboxing,每次得到的对象都是同一个。