五月的深圳空氣中瀰漫起初夏的味道,淡淡的,暖暖的。春日裏不太張揚的陽光也摻入這股氣息...(煙哥好文采!)
這天,煙哥愉快的喝着霸氣芝士莓莓莓。一邊東張西望,尋找着能夠裝13的機會。一切正以下面這張圖這樣
這時,小劉出現了!沒錯,就是那個你們期待的小劉出現了!她拿着一本《XXXjava筆試指南》來找煙哥。
只見小劉嫺熟的打開這本書,望着整本書滿滿的筆記,煙哥不由猜想道:"小劉如此熱衷於學習,必定仍是單身。"想到這裏,煙哥不由更有回答的動力了(沒錯,我就是這種人!)。java
小劉翻到某一頁後,指出下面這樣一道題緩存
public static void main(String[] args){ Integer a = 50; Integer b = 50; Integer c = 150; Integer d = 150; System.out.println(a==b); System.out.println(c==d); }
輸出結果爲函數
true false
而後詢問煙哥具體原因。
煙哥看完之後,心裏正(wei)直(suo)的笑了笑,內心想道:"這不是幾年前的老題目了麼,怎麼如今還在考!"
煙哥回答道:"其實很簡單,原理是下面這樣滴!"
JAVA編譯器編譯Integer a = 50的時候,被翻譯成-> Integer a = Integer.valueOf(50);
而valueOf
的源碼是下面這樣的學習
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
看到了嘛,Integer內部有一個IntegerCache緩存。對於值範圍在-128到127之間的數,會進行緩存。所以a和b範圍在-128到127之間,因此指向的是同一個對象,因此判斷結果是true
。而c和d在128以外,因此每次都是返回一個新對象,因此判斷結果是false
。
聽到這裏,小劉彷佛很滿意的準備打道回府。
"不行,怎麼能這樣讓小劉離開。我得多和小劉說說話!"
因而,煙哥說道:"小劉阿,其實java筆試裏關於數值方面的陷阱,能夠玩出不少花樣,你瞭解多少?"
很天然的,小劉的表情是下面這樣的
測試
煙哥說道:"這樣吧,先問你一個問題。Math.abs(Integer.MIN_VALUE))
的結果是正數仍是負數?"
小劉:"Math.abs
是絕對值運算,結果應該是正數吧。"
煙哥:"不對,仍是負數。Integer的範圍爲-2147483648~2147483647。不過咱們先來看一眼abs
函數的源碼,以下所示"翻譯
public static int abs(int a) { return (a < 0) ? -a : a; }
煙哥:"看了源碼,其實很明顯,絕對值運算的原理是判斷這個數是否大於零,若是小於零則取負值。OK,回到咱們題目。Integer.MIN_VALUE
,它的十六進制表示是 0x80000000。其符號位爲1,其他全部的位都是0。取負數(反碼+1)則爲 0x7fffffff+1,也就是 0x80000000。你會發現對Integer.MIN_VALUE
取負值仍是自己。所以,結果仍是負數。"
小劉:"那你這套理論對Long
、Short
、Byte
都成立麼?"
煙哥:"是的,都是成立的,原理都同樣。你能夠回去測試一下以下代碼"3d
Short num =(short)Math.abs(Short.MIN_VALUE)); System.out.println(num);
小劉望着這些代碼,陷入了思考...
忽然,小劉回答道:"好像,以前我有看到一個題目是這樣的。是否存在一個數i,可使得i+1<i
,這樣看來,這個i就是Integer.MAX_VALUE
,由於加完1就溢出了變爲負值了。"
聽小劉說道這裏,煙哥換了一個角度問:"是否存在一個數,知足i != 0 && i == -i
"
小劉想了下,機智的回答道:"其實仍是Integer.MIN_VALUE
,緣由你剛纔說過了!"
唉,沒想到小劉領悟如此的快!code
煙哥感慨小劉領悟速度的同時,加大難度問道:"是否存在一個數,知足i==i+1
?"
小劉忽然懵了,答道:"好像..彷佛..應該一個數永遠不會等於本身加一。"
看見小劉懵圈的眼神,煙哥只見本身裝13的目的已經達到,便再也不賣關子...
煙哥回答道:"有沒聽過一句話,無窮大加一個常數仍是無窮大!因此,下面的例子輸出爲true
"對象
double i = Double.POSITIVE_INFINITY; System.out.println(i == i+1);
小劉反懟煙哥,說道:"其實,無窮大減去一個常數也是無窮大。因此下面例子也是輸出爲true
,並且無窮小也有相似的特性。"blog
double i = Double.POSITIVE_INFINITY; System.out.println(i == i-1);
煙哥滿意的點了點頭,感慨小劉成長真快!
忽然,靈光一閃,煙哥補充道:"你知不知道有一個數能夠知足i!=i
?"
小劉再次陷入了深思...嘴裏嘟囔道:"奇怪,還有一個數能夠本身不等於本身麼?"
望着小劉愁眉苦臉的眼神 ,煙哥答道:"對,有一個不是數值的值,它就是NaN
,翻譯過來就是(Not a Number),所以下面的輸出是爲true
!"
double i = Double.NaN; System.out.println(i != i);
在煙哥一陣裝13後,決定暴露本身的本性。問道:"小劉,你有對象了麼?"
小劉答道:"煙哥,你是個好人,然而我已經有對象了!"
"Boom!"
(本文完!)