(5):避免创造不必要对象
2017-03-29 16:44
113 查看
一般来说,最好是能重用已有的对象,而不是每次有需要的时候就去创建一个相同功能的对象。比较下面两个例子
(1).String s1 = “string1”;
(2).String s2 = new String(“string1”);
(2)比(1)多创造出了许多不必要的对象。由于String被实现为不可变对象,JVM底层将其实现为常量池,既所有值等于"string1" 的String对象实例共享同一对象地址,而且还可以保证,对于所有在同一JVM中运行的代码,只要他们包含相同的字符串字面常量,该对象就会被重用。所以(1)可以重用已经存在的“string1”对象。而(2)却开辟了新的内存,这就大大浪费了内存。
除了重用不可变的对象之外,也可以重用那些已知不会被修改的对象。仔细观察下面两个例子:
Calendar,TimeZone,boomStart和boomEnd四个对象是所有调用者共用的对象,只需创建一份即可,改进之后代码如下:
这样Person类只在初始化时创建Calendar,TimeZone,boomStart和boomEnd四个对象一次,如果isBabyBoomer()被频繁调用,性能就可以得到明星提高。
在java 1.5版本中,有一种创建多余对象的方法,称作自动装箱。看下面的例子
将sum声明的由Long类型改为原始类型的long,由于省去了2的31次方不必要的类型自动封装,程序大概耗时6秒,性能提高7倍。所以要尽量使用基本类型。
最后要注意但重用对象而付出的代价远远大于创建对象的代价时,这条建议就未必适用了。
(1).String s1 = “string1”;
(2).String s2 = new String(“string1”);
(2)比(1)多创造出了许多不必要的对象。由于String被实现为不可变对象,JVM底层将其实现为常量池,既所有值等于"string1" 的String对象实例共享同一对象地址,而且还可以保证,对于所有在同一JVM中运行的代码,只要他们包含相同的字符串字面常量,该对象就会被重用。所以(1)可以重用已经存在的“string1”对象。而(2)却开辟了新的内存,这就大大浪费了内存。
除了重用不可变的对象之外,也可以重用那些已知不会被修改的对象。仔细观察下面两个例子:
public class Person{ private Date birthDate; //判断是否是婴儿潮出生的人 public boolean isBabyBoomer(){ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(“GMT”)); //婴儿潮开始时间 cal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); Date boomStart = cal.getTime(); //婴儿潮结束时间 cal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = cal.getTime(); return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; } }每次调用isBabyBoomer()方式时,都需要创建Calendar,TimeZone,boomStart和boomEnd四个对象,测试调用该方法1000万次,大约耗时32秒。
Calendar,TimeZone,boomStart和boomEnd四个对象是所有调用者共用的对象,只需创建一份即可,改进之后代码如下:
public class Person{ private Date birthDate; private static final Date BOOM_START; private static final Date BOOM_END; static{ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(“GMT”)); //婴儿潮开始时间 cal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = cal.getTime(); //婴儿潮结束时间 cal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = cal.getTime(); } //判断是否是婴儿潮出生的人 public boolean isBabyBoomer(){ return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0; } }
这样Person类只在初始化时创建Calendar,TimeZone,boomStart和boomEnd四个对象一次,如果isBabyBoomer()被频繁调用,性能就可以得到明星提高。
在java 1.5版本中,有一种创建多余对象的方法,称作自动装箱。看下面的例子
public CalculateInt{ 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封装为Long),总共耗时大约43秒。
将sum声明的由Long类型改为原始类型的long,由于省去了2的31次方不必要的类型自动封装,程序大概耗时6秒,性能提高7倍。所以要尽量使用基本类型。
最后要注意但重用对象而付出的代价远远大于创建对象的代价时,这条建议就未必适用了。
相关文章推荐
- Effective java第五条:避免创造不必要的对象
- 一个静态初始化器的应用--避免创造不必要的对象
- Effective Jave 创建和销毁对象 5.避免创建不必要的对象
- 创建和销毁对象——避免创建不必要的对象——重用那些已知不会被修改的可变对象。
- Effective Java(避免创建不必要的对象、消除过期的引用对象)
- Effective Java 读书笔记(五):Java避免创建不必要的对象
- 【Effective Java】3、避免创建不必要的对象
- 五、避免创建不必要的对象
- 创建和销毁对象(3)(4)——避免创建不必要的对象,消除过期对象
- 第5条:避免创建不必要的对象
- Effective Java(避免创建不必要的对象、消除过期的引用对象)
- EffectiveJava(5)避免创建不必要的对象
- 避免创建不必要的对象
- 第五条:避免创建不必要的对象
- 学习effective java-5创建和销毁对象之避免创建不必要的对象
- 避免创建不必要的对象
- 《Effective Java》读书笔记04--避免创建不必要的对象
- 05、避免创建不必要的对象
- 5、避免创建不必要的对象
- Effective Java(避免创建不必要的对象、消除过期的引用对象)