一、不可變類的實例狀態不可改變,能夠被多個對象很方便的共享java
二、若是程序常常使用某個不可變類的實例,那麼把該實例保存近緩存是一個好的選擇,不用每次都生成新的實例對象,消耗系統開銷數組
以下代碼實例:將建立的不可變類實例進行緩存緩存
import static java.lang.System.*; import java.util.Arrays; class CacheImmutable{ //-定義緩存數組的長度,私有的,靜態的,不可更改的 private static final int MAX_SIZE=3; //-定義緩存數組,來緩存已有的實例,靜態的,不可更改的,不變類的要素之一 private static final CacheImmutable[] cache = new CacheImmutable[MAX_SIZE]; //-記錄緩存實例在緩存中的位置,cache[pos-1]是最新緩存進來的實例 private static int pos=0; //-記錄當前實例的name,不可更改的,每一個實例的name都不一樣,因此不能是static修飾 private final String name; //-獲取當前實例的name,只設置獲取getter方法,不設置設置setter方法,不變類的要素之一 public String getName(){ return this.name; } //-帶參數的構造器,name賦值的惟一路徑,private修飾,不能外部new新的實例,不變類的要素之一 private CacheImmutable(String name){ this.name=name; } //-獲取類實例對象的惟一方式 public static CacheImmutable valueOf(String name){ //-循環緩存數組,判斷新定義的實例對象是否已經存在,如存在,直接返回已有的實例,再也不存入新的實例 for(int i=0;i<MAX_SIZE;i++){ if(cache[i]!=null&&cache[i].getName().equals(name)){ return cache[i]; } } //-若是緩存數組已經存滿,新的實例覆蓋第一個舊實例,並把位置標爲 1,若是緩存沒滿,保存進緩存,位標+1,並返回該實例 if(pos==MAX_SIZE){ cache[0] = new CacheImmutable(name); pos=1; }else{ cache[pos++] = new CacheImmutable(name); } return cache[pos-1]; } //-重寫Object類的equals()方法 public boolean equals(Object obj){ if(this==obj){ return true; } if(obj!=null&&obj.getClass()==CacheImmutable.class){ CacheImmutable ci = (CacheImmutable)obj; if(this.getName().equals(ci.getName())){ return true; } } return false; } //-重寫Object類的hashCode()方法 public int hashCode(){ return name.hashCode(); } //-獲取當前實例在緩存中是第幾個 public int getPos(){ return pos; } //-獲取整個緩存數組 public CacheImmutable[] getArray(){ return cache; } } public class CacheImmutableTest{ public static void main(String[] args){ //-定義一個 CacheImmutable類實例:cache1,name爲:ImmutableClass,並保存進緩存 CacheImmutable cache1 = CacheImmutable.valueOf("ImmutableClass"); //-輸出當前實例在緩存中的位置 out.println(cache1.getPos()); //-遍歷整個緩存,輸出緩存中每一個實例的name值 for(int i=0;i<cache1.getPos();i++){ out.println(cache1.getArray()[i].getName()); } //-輸出整個緩存數組 out.println(Arrays.toString(cache1.getArray())); out.println(); //-新定義的實例:cache2 與 已經保存進緩存的實例:cache1的name值相等,因此視爲已存在實例,不會再次進緩存 CacheImmutable cache2 = CacheImmutable.valueOf("ImmutableClass"); out.println(cache2.getPos()); for(int i=0;i<cache2.getPos();i++){ out.println(cache2.getArray()[i].getName()); } out.println(Arrays.toString(cache2.getArray())); out.println(); CacheImmutable cache3 = CacheImmutable.valueOf("ImmutableClass_a"); out.println(cache3.getPos()); for(int i=0;i<cache3.getPos();i++){ out.println(cache3.getArray()[i].getName()); } out.println(Arrays.toString(cache3.getArray())); out.println(); CacheImmutable cache4 = CacheImmutable.valueOf("ImmutableClass_b"); out.println(cache4.getPos()); for(int i=0;i<cache4.getPos();i++){ out.println(cache4.getArray()[i].getName()); } out.println(Arrays.toString(cache4.getArray())); out.println(); out.println(cache1.equals(cache2)); out.println(cache1.equals(cache3)); out.println(); //-新定義的實例:cache5,會覆蓋緩存數組中的第一個實例(由於緩存已滿), CacheImmutable cache5 = CacheImmutable.valueOf("ImmutableClass_c"); out.println(cache5.getPos()); for(int i=0;i<cache5.getPos();i++){ out.println(cache5.getArray()[i].getName()); } out.println(Arrays.toString(cache5.getArray())); } }
運行效果:性能
總結:this
一、是否須要隱藏類的構造器,徹底取決於系統需求對象
二、盲目亂用緩存可能致使系統性能降低blog
三、緩存的對象會佔用內存,若是對象只用一次,重複使用的機率不大,緩存該實例就弊大於利內存
四、若是某個對象須要頻繁的調用,緩存該實例就利大於弊ci
Java提供的Integer類,就採用了上面CacheImmutable類相同的緩存策略:get
一、若是採用 new 構造器來建立 Integer 對象,返回的是全新的 Integer 對象
二、若是採用 valueOf() 方法來建立 Integer 對象,則在建立該對象的同時,會緩存該方法建立的對象
三、Integer 只緩存 -128-127之間的 Integer 對象,超過該範圍的對象不會緩存
以下代碼示例:
public class IntegerCache{ public static void main(String[] args){ //-生成新的Integer對象實例:a Integer a = new Integer(5); //-生成新的Integer對象實例:b,並緩存 Integer b = Integer.valueOf(5); //-直接從緩存裏獲取對象,由於緩存裏相同對象已經存在 Integer c = Integer.valueOf(5); //-false System.out.println(a==b); //-true System.out.println(b==c); //-Integer只緩存-128-127之間的值,200對應的Integer對象沒有被緩存 Integer d = Integer.valueOf(200); Integer e = Integer.valueOf(200); //-由於沒緩存,因此是兩個不一樣的對象,返回false System.out.println(d==e); } }
運行結果: