避免创建不必要的对象
一般来说,最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。重用方式既快速,又流行。如果对象是不可变的,它就始终可以被重用。
例如避免使用:
String s = new String("stringette"); // Dont DO THIS
改进为使用:
String s = "stringette";
这是一个简单且清晰明了的改进,并且性能提升很多。
静态工厂可避免创建不必要的对象,且几乎优于构造器。
使用静态块也可以使实例只初始化一次,大量调用的时候可以明显提升性能(适用于不会被修改的对象),比如Calender、Date等
如果方法永远不会被调用,那么使用延迟初始化,使得方法在第一次调用的时候才初始化可以解决。但不建议这样做,这样做会使得方法实现更加复杂,从而无法将性能显著提高到超过已有的水平。
在Java 1.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而不是long。意味着大约构建了2的31次方个Long的实例。实际的运行实际是43和6.8秒。所以优先的使用基本类型而不是装箱类型,要当心无意识的自动装箱。
另外不要错误的认为创建对象的代价非常昂贵,小对象的创建 和回收时很廉价的,通过创建附加对象提升程序的清晰性、简洁性和功能性时非常good的。
反之通过对象池来避免创建对象不一定是好事情,当然重量级的对象基本还是需要对象池来进行管理,最简单的就是线程和数据库链接。
与本条对应的条目是19条中的“保护性拷贝”的内容。本条目讨论“应当重用对象的时候,不要创建新的对象”,而39条“当你应该创建对象的时候,请不要重用对象”。注意,在提倡使用保护性拷贝的时候,因重用对象而付出代价要远远大于因创建对象而付出的代价。必要时如果没有实施保护性拷贝,将会导致潜在的错误和安全漏洞;而不必要的创建对象则会影响程序的风格和性能。(本人的建议就是合理的考究使用性,除了一些很明显的必要遵守的规则以外,哪个性价比高就用哪一个,这里属实有点绕了)