讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議133:若非必要,不要克隆對像 >

建議133:若非必要,不要克隆對像

通過clone方法生成一個對像時,就會不再執行構造函數了,只是在內存中進行數據塊的拷貝,此方法看上去似乎應該比new方法的性能好很多,但是Java的締造者們也認識到「二八原則」,80%(甚至更多)的對象是通過new關鍵字創建出來的,所以對new在生成對像(分配內存、初始化)時做了充分的性能優化,事實上,一般情況下new生成的對象比clone生成的性能方面要好很多,例如這樣的代碼。


private static class Apple implements Cloneable{

public Object clone(){

try{

return super.clone();

}catch(CloneNotSupportedException e){

throw new Error();

}

}}

public static void main(Stringargs){

//循環10萬次

final int maxLoops=10*10000;

int loops=0;

//開始時間

long start=System.nanoTime();

//"母"對像

Apple apple=new Apple();

while(++loops<maxLoops){

apple.clone();

}

long mid=System.nanoTime();

System.out.println("clone方法生成對像耗時:"+(mid-start)+"ns");

//new生成對像

while(--loops>0){

new Apple();

}

long end=System.nanoTime();

System.out.println("new生成對像耗時:"+(end-mid)+"ns");

}


在上面的代碼中,Apple是一個簡單的可拷貝類,用兩種方式生成了10萬個蘋果:一種是通過克隆技術,一種是通過直接種植(也就是new關鍵字),按照我們的常識想當然地會認為克隆肯定比new要快,但是結果卻是這樣的:


clone方法生成對像耗時:18731431 ns

new生成對像耗時:2391924 ns


不用看具體的數字,數數位數就可以了:clone方法花費的時間是8位數,而new方法是7位數,用new生成對像比clone方法快很多!原因是Apple的構造函數非常簡單,而且JVM對new做了大量的性能優化,而clone方式只是一個冷僻的生成對像方式,並不是主流,它主要用於構造函數比較複雜,對像屬性比較多,通過new關鍵字創建一個對像比較耗時間的時候。

注意 克隆對象並不比直接生成對像效率高。