通常來講,咱們最好的作法是重用對象,而不是每次使用都new出一個新的相同功能的對象,這樣作很高效,特別是對於那些不可變類來講。看一個極端的反面例子,若是String s = new String("stringette");每次都被執行的話都會建立一個新的實例,然而stringette自己就是String一個實例,功能和構造器建立的對象等,若是這種用法在一個for循環中,或者被頻繁調用,那就會創形成千上萬個String實例了。所以,使用 String s = "stringette"就不是每次執行的時候都建立一個新的實例,在同一臺虛擬機中運行的代碼,只要包含相同的字符串字面常量,該對象就會被重用。性能
如今咱們來看一個例子,好比有一個Person對象,對象中有一個字段是生日,生日是個常量,它不能被更改,如今須要完成一個方法,用這個方法咱們能夠獲取到這我的是否出生在1946到1964年之間(也就是生育高峯期(baby boomer))this
public class Person { private final Date birthday; public Person(Date birthday) { this.birthday = birthday; } public boolean isBabyBoomer() { Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); //將時間設置爲1946年1月1日0時0分0秒 c.set(1946, Calendar.JANUARY, 1, 0, 0, 0); Date boomStart = c.getTime(); c.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = c.getTime(); return birthday.compareTo(boomStart) >= 0 && birthday.compareTo(boomEnd) < 0; } }
從上面的isBabyBoomer能夠看出,若是咱們每次調用這個方法,都會新建一個Calendar、兩個Date對象實例,這些都是沒必要要的,於是,咱們如今對Person進行修改下已達到代碼的重用。spa
public class Person { private final Date birthday; private static final Date BOOM_START; private static final Date BOOM_END; public Person(Date birthday) { this.birthday = birthday; } static { Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); //將時間設置爲1946年1月1日0時0分0秒 c.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = c.getTime(); c.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = c.getTime(); } public boolean isBabyBoomer() { return birthday.compareTo(BOOM_START) >= 0 && birthday.compareTo(BOOM_END) < 0; } }
好了,這樣就很明顯的能夠看出,咱們不須要每次都建立新的Calendar和Date對象實例了。code
建議:若是想要保證性能,則儘可能使用基本數據類型而不是裝箱基本類型,要小心無心識的自動裝箱。如Integer k = 10;對象
總結:本條的重點是避免建立多餘的對象,提升重用性,可是須要注意對象的重用不能是盲目的,對於對象的重用,咱們應該把目光集中在那些重量級的類,或是構造方法中須要作不少初始化的類的身上。對於一些比較輕量級的類,咱們應該將代碼的簡潔和可維護性放在跟高的優先級上。blog