在實際開發中,重復使用同一個對象要比每次需要的時候就創建一個對象要好的多;
作為一個比較極端的反面例子,看下面這個語句:
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