26 October 2011



如果有一個Integer的物件要宣告,
大部分的人宣告方式會是如下
Integer a = new Integer(2);

但如果其value是介於-128~127之間,
某些時刻可以使用下面的宣告方式
Integer a = Integer.valueOf(2);

某些條件下,速度較快一點點點!!
為什麼呢?? 我們來看下面的例子!

/*
* 如果不是用new Integer()去賦予值,
* 如果是下方的宣告方式,都會去call Integer.valueOf()這個method
* 也就是說下方的宣告方式,a=2 如同 a=Integer.valueOf(2)
*/
Integer a = 3;
Integer b = 3;
System.out.println( a==b ); //印出來會是什麼?

如果你的答案是false,只能說不完全錯
因為你的想法,可能是認為==是用來比較2個物件的位址是否相同。
如果你是這樣想,那你觀念對了,可是就是忽略掉了valueOf的cache機制。
這算是一個陷阱。

如果你的答案是true,只能說不完全對
因為得取決於你的想法,

  1. 如果你認為因為a是3,b也是3,3等於3阿,所以是true,那就大錯特錯了。你的觀念需要加強。因為==是比較2個物件的位置是否相同,也就說用來判斷是否為同個物件,並不是判斷value是否相同。
  2. 如果你是認為因為==是比較位置,且知道valueOf有cache機制,所以為true,那你答對了。

因為在call valueOf這個method時,
此method裡面會有判斷是否要調用cache的code,
如下,
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}

也就是說如果value是介於-128~127之間,
就會掉入到if裡面,而IntegerCache為一個class,
在使用這個class時就會去new 256個Integer的物件,並放入cache中,
所以在上面的例子a跟b的value都是3,
自然會調用同一塊cache,所以用==在比較時,他們的記憶體位置自然為同一塊。
因此答案為TRUE。

最後!!!
或許有人會覺得奇怪,cache會去new 256個Integer物件耶!!
這樣用valueOf怎麼會比較快呢??
上面有說到某些條件下,該條件就是,
如果是大量宣告的話,此時調用valueOf比較快的條件就成立了。


我們可以寫一小段code來判斷執行時間,如下
long lStart = System.nanoTime();
for (int i = 0; i < 1000000000 ; i++) {
Integer a = new Integer(3);
}
long lEnd = System.nanoTime()-lStart;

System.out.println((float) lEnd/1000000000);

lStart = System.nanoTime();
for (int i = 0; i < 1000000000 ; i++) {
Integer a = Integer.valueOf(3);
}
lEnd = System.nanoTime()-lStart;
System.out.println((float) lEnd/1000000000);

可以發現上面的例子,
用new Integer的方法大概都快要1秒鐘,差不多為0.6秒,
但調用Integer.valueOf()的方法大概0.003秒,
當然其實人感覺不太到差異啦。
只是說硬要評比的話,valueOf的方法較為快。
但記得!! 必須符合大量資料的前提才成立。







blog comments powered by Disqus