不可改變類是其執行個體對象不可改變,有人可能會想這還不簡單,我們不提供改變對象
內部狀態的API不就完了,沒錯,這是一個很重要的一條,但還有很多注意點
首先為什麼要建立不可改變的類?
不可改變類比可變類更加易於設計、實現和使用。它們不容易出錯,且更加安全,在Java平台有很多不可改變類,如:String , 基本類型封裝類、BigInteger BigDecimal
為使一個類不可改變,遵守下面五條規則:
1.不要提供任何會修改對象狀態的方法
2.保證類不會被擴充(定義為final 類,也可以提供私人構造,然後提供靜態Factory 方法)
3.使所有的域都是final
4.使所有的域都是私人的
5.確保對於任何可變組件的互斥訪問(如果類具有指向可變對象的域,則必需確保該類的用戶端無法獲得指向這些對象的引用)
然後不可變域也有不好的地方,就是第次修改都會產生一個新的對象,這將會大大影響
效率,我們可以考慮下面的情況 :
Integer sum = 0;
for(int i=0;i<100000;i++)
sum+=i;
這樣下來,我們可想而知,系統裡將會產生多少個Integer 對象,這將會大大影響效率,
其實Integer 在這方面已經做出來了最佳化,具體方案如下:
1.我們可以把經常使用到的對象提供給公有final 對象,如果BigInteger 中的ONE、TEN、zero
2.我們可以用一個靜態Factory 方法,將頻繁使用的對象緩衝起來了,這樣每次我們調用的時候就可以直接返回緩衝起來的值,而不用再次去建立相同的對象,下面是Integer中的做法,它是將一個位元組所表示的有符號整形資料,而它的緩衝則是放在了一個私人的靜態內部類裡面
private static class IntegerCache {private IntegerCache(){}static final Integer cache[] = new Integer[-(-128) + 127 + 1];static { for(int i = 0; i < cache.length; i++)cache[i] = new Integer(i - 128);} }
下面是靜態Factory 方法:
public static Integer valueOf(int i) {final int offset = 128;if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset];} return new Integer(i); }