在實際開發中,重復使用同一個對象要比每次需要的時候就創建一個對象要好的多;
作為一個比較極端的反面例子,看下面這個語句:
String s = new String("haha");
改語句每次被執行時都會創建一個新的String實例,如果這種用法是在一個循環中,或者是在一個被頻繁調用的方法中,將會有成千上萬個String實例被創建,這樣的做法是沒有必要的,可改進成如下這樣:
String s = “haha”;
這個版本只使用一個String實例,而不是每次被執行的時候都創建了一個實例。對於在同一個虛擬中,運行的代碼,只要包含相同的字符串字面常量,則改對象就會被重用。
除了重用非可變的對象外,對於那些已知不會被修改的可變對象,也是可以重用它們,看個比較常見的例子:
1 public class Person{ 2 private final Date birthDate; 3 4 public Person(Date birthDate){ 5 this.birthDate = birthDate; 6 } 7 8 public boolean isBabyBoomer(){ 9 Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 10 11 gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); 12 Date boomStart = gmtCal.getTime(); 13 14 gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); 15 Date boomEnd = gmtCal.getTime(); 16 17 return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; 18 } 19 20 }
isBabyBoomer每次被調用的時候,都會創建一個新的Calendar, 一個新的TimeZone,兩個新的Date對象,這是不必要的,下面的版本使用一個靜態的初始化器,避免了上面例子的低效:
1 public class Person{ 2 private final Date birthDate; 3 4 public Person(Date birthDate){ 5 this.birthDate = birthDate; 6 } 7 8 private static final Date BOOM_START; 9 private static final Date BOOM_END; 10 11 static{ 12 Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 13 14 gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); 15 BOOM_START = gmtCal.getTime(); 16 17 gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); 18 BOOM_END = gmtCal.getTime(); 19 } 20 21 public boolean isBabyBoomer(){ 22 return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; 23 } 24 25 }
改進版本的Person類僅在初始化時刻創建Calendar、TimeZone和Date實例一次,而不是在每次isBadyBoomer被調用的時候創建它們。
摘自Effective java