一般來說,最好能重用物件而不是在每次需要的時候就建立乙個相同功能的新物件。重用方式既快速,又流行。如果物件是不可變的,它就始終可以被重用。
最為乙個極端的反面例子,考慮下面的語句:
string s = new string("string");// don't do this!
該語句每次被執行的時候都建立乙個新的string例項,但是這些建立物件的動作全都是不必要的。傳遞給string構造器的引數("string")本身就是乙個string例項,功能方面等同於構造器建立的所有物件。如果這種用法是在乙個迴圈中,或者是在乙個被頻繁呼叫的方法中,就會建立出成千上萬不必要的string例項。改進後:string s="stirng";
這個版本只用了乙個stirng例項,而且每次執行的時候都建立乙個新的例項。而且,它可以保證,對於所有的同一臺虛擬機器中執行的**,只要它們包含相同的字串字面常量,該物件就會被重用。
例如:靜態工廠方法boolean.valueof(string)幾乎總是優先於構造器boolean(string)。構造器在每次被呼叫的時候都會建立乙個新的物件,而靜態工廠方法則從來不要求這樣做,實際上也不會這樣做。
public class person
}
看看這段**有什麼不妥,isbabyboomer每次被呼叫的時候,都會新建乙個calendar,乙個timezone和兩個date例項,這是不必要的,下面的版本用乙個靜態的初始化器,避免了這種效率低下的情況:
class person
public boolean isbabyboomer()
}
改進後的person類只在初始化的時候建立calendar,timezone和date例項一次,而不是在每次呼叫isbodyboomer的時候都建立這些例項。如果isbodyboomer方法被頻繁的呼叫,這種方法將會顯著提高效能,**的含義也更加清晰,但是這種優化並不總是那麼明顯,因為calendar例項的建立代價特別昂貴。
如果改進後的person類被初始化了,他的isbodyboomer方法卻永遠不會被呼叫,那就沒有必要初始化boom_start,boom_end域。通過延遲載入,即可對這些域的初始化延遲到isbodyboomer方法第一次被呼叫的時候進行,則有可能消除這些不必要的初始化工作,但是不建議這樣做。正如延遲初始化中常見的情況,這樣會使方法的實現更加複雜,從而無法將效能顯著提高到超過已經達到的水平。
再如:自動裝箱問題
public static void main(string args){
long sum=0l;
for(long i = 0; i這段程式算出的答案是正確的,但是比實際情況要慢些,因為之前宣告的sum是long型,而不是long型,這樣在執行的時候就會建立出2的31次方個例項,會大大消減效率,結論很明顯:要優先使用基本型別而不是裝箱基本型別,要當心無意識的自動裝箱。
不要錯誤的以為本文介紹的內容暗示「建立物件的代價非常昂貴,我們應該盡可能地避免建立物件」。相反,由於小物件的構造器只做很少量的顯示工作,所以,小物件的建立和**動作是非常廉價的,特別是在現在的jvm實現上更是如此。通過建立附加的物件,提公升程式的清晰性,簡潔性和功能性,這通常是件好事。
避免建立不必要的物件
下面是乙個比較微妙也比較常見的反面的例子,其中涉及可變的date物件,他們的值一旦計算出來之後就不再變化。這個類建立了乙個模型 其中有乙個人,並有乙個isbabyboomer方法,用來檢驗這個人是否為乙個babyboomer,換句話說,就是檢驗這個人是否出生於1946年至1964年之間。public...
建議 避免建立不必要的物件。
一般來說,最好能重用物件而不是在每次需要的時候就建立乙個相同功能的新物件。重用方式既快速,又流行。如果物件時不可變的 immutable 它就始終可以被重用。作為乙個極端的反面例子,考慮下面的語句 string s new string stringette don t do this 該語句每次被...
避免不必要的float
float中文翻譯為浮動,很形象的翻譯,在css很常用,當你需要吧兩個塊級元素定排放在同一高度上經常會用到float,先看一下float的 屬性。先看一下float可能的值 float left 元素向左浮動 float right 元素向右浮動 float none 不浮動 float inher...