不可變類的實例的狀態不會變化這樣的實例可以安全地被其他與之關聯的對象共享還可以安全地被多個線程共享為了節省內存空間優化程序的性能應該盡可能地重用不可變類的實例避免重復創建具有相同屬性值的不可變類的實例
在JDK 的基本類庫中對一些不可變類如Integer類做了優化它具有一個實例緩存用來存放程序中經常使用的Integer實例JDK 的Integer類新增了一個參數為int類型的靜態工廠方法valueOf(int i)它的處理流程如下
if(在實例緩存中存在取值為i的實例)
直接返回這個實例
else{
用new語句創建一個取值為i的Integer實例
把這個實例存放在實例緩存中
返回這個實例
}
在以下程序代碼中分別用new語句和Integer類的valueOf(int i)方法來獲得Integer實例
Integer a=new Integer();
Integer b=new Integer();
Integer c=IntegervalueOf();
Integer d= IntegervalueOf();
Systemoutprintln(a==b); //打印false
Systemoutprintln(a==c); //打印false
Systemoutprintln(c==d); //打印true
以上代碼共創建了個Integer對象每個new語句都會創建一個新的Integer對象而IntegervalueOf()方法僅在第一次被調用時創建取值為的Integer對象在第二次被調用時直接從實例緩存中獲得它由此可見在程序中用valueOf()靜態工廠方法獲得 Integer對象可以提高Integer對象的可重用性
到底如何實現實例的緩存呢?緩存並沒有固定的實現方式完善的緩存實現不僅要考慮何時把實例加入緩存還要考慮何時把不再使用的實例從緩存中及時清除以保證有效合理地利用內存空間一種簡單的實現是直接用Java集合來作為實例緩存
下面的例程它擁有實例緩存和相應的靜態工廠方法valueOf()Name類的實例緩存中可能會加入大量Name對象為了防止耗盡內存在實例緩存中存放的是Name對象的軟引用(SoftReference)如果一個對象僅僅持有軟引用Java虛擬機會在內存不足的情況下回收它的內存
例程 Namejava
import javautilSet;
import javautilHashSet;
import javautilIterator;
import javalangref*;
public class Name {
…
//實例緩存存放Name對象的軟引用
private static final Set> names=new HashSet>();
public static Name valueOf(String firstname String lastname){ //靜態工廠方法
Iterator> it=namesiterator();
while(ithasNext()){
SoftReference ref=itnext();//獲得軟引用
Name name=refget();//獲得軟引用所引用的Name對象
if(name!=null&& namefirstnameequals(firstname)&& namelastnameequals(lastname))
return name;
}
//如果在緩存中不存在Name對象就創建該對象並把它的軟引用加入到實例緩存
Name name=new Name(firstnamelastname);
namesadd(new SoftReference(name));
return name;
}
public static void main(String args[]){
Name n=NamevalueOf(小紅王);
Name n=NamevalueOf(小紅王);
Name n=NamevalueOf(小東張);
Systemoutprintln(n);
Systemoutprintln(n);
Systemoutprintln(n);
Systemoutprintln(n==n); //打印true
}
}
在程序中既可以通過new語句創建Name實例也可以通過valueOf()方法創建Name實例在程序的生命周期中對於程序不需要經常訪問的 Name實例應該使用new語句創建它使它能及時結束生命周期;對於程序需要經常訪問的Name實例那就用valueOf()方法來獲得它因為該方法能把Name實例放到緩存中使它可以被重用
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27247.html