精選Java基礎知識講解,看看能答對多少?
沒有技術深度是大多程式設計師的一種常態。
Integer比較
看下面這段有意思的程式碼,對數字比較敏感的夥伴有沒有發現異常?
public static void main(String[] args) { Integer a = 128,b=128; Integer c = 127,d=127; System.out.println(a==b); System.out.println(c==d); }
如果你的答案是false,false,可能你有一定的基礎,知道Integer是個封裝類別。當然如果你的答案是true,true的話,也在一定的認知範圍之內,但是基礎知識掌握的不夠好。
好了,我們運行main方法,正確答案應該是false,true。前幾年這題出現在很多面試題中,當然你也會說了,我會做專案就ok了,用到查就是了,何必要知道,這我沒話說。
其實當我們給一個Integer物件賦一個int值的時候,會呼叫Integer類別的靜態方法valueOf,讓我們看下原始程式碼是怎麼實現的。
IntegerCache方法有明確的註釋,快取範圍,如何修改等等。
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the -XX:AutoBoxCacheMax=<size> option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
神奇不神奇,其實程式碼描述的很清晰,如果整數字面量的值介於-128到127之間,就不會new一個新的Integer對象,而是直接引用常數池中的Integer對象,所以上面的運行結果是a==b=false,而c==d=true。
String比較
接下來這題,相對來說應該比較簡單了。
public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System.out.println(s1 == s2); System.out.println(s1 == s3); }
小夥伴們看了是不是很熟悉?可能有的人一眼就掃出了答案true,false。當然沒有掃出正確答案的夥伴們也不要氣餒,下面跟大家分析分析為毛是這麼一個答案。
依照==的語法來看, 首先s1、s2、s3是三個不同的對象,常理來說,輸出都會是false。然而程式的運行結果確實true、false。第二個輸出false可以理解,第一個輸出true就又讓人費解了。
我們知道一些基本型別的變數和物件的參考變數都是在函數的堆疊記憶體中分配,而堆疊記憶體中則存放new 出來的物件和陣列。然而除此之外還有一塊區域叫做常量池。
像我們通常想String s1 = "abc";這樣申明的字串對象,其值就是儲存在常數池中。當我們建立String s1 = "abc"這樣一個物件之後,"abc"就儲存到了常數池(也可叫做字串池)中。
當我們建立引用String s2 = "abc" 的時候,Java底層會優先在常數池中尋找是否存在"abc",如果存在則讓s2指向這個值,不會重新創建,如果常數池中沒有則建立並新增的池中。這就是為什麼答案是true 和false的原因。
Integer與int比較
public static void main(String[] args) { Integer a = new Integer(128); int b = 128; Integer c = new Integer(6); Integer d = new Integer(6); System.out.println(a == b); System.out.println(c == d); }
相信又有不少小夥伴懵比了吧,ture還是false?還是直接公佈答案吧,true,false。
c == d=false,我覺得沒什麼好說的,可能有的小夥伴要問了不是-128-127被緩存起來了麼?但是我們這裡的Integer是new出來的,並不是用的緩存,所以結果是false。
a == b=true,大家注意一下這裡的b是int型,當int和Integer做==比較的時候,Integer型別會自動拆箱,也就是把Integer轉成int型,所以這裡進行比較的是int型別的值,所以結果就是true。
以上是Java基礎知識精選的分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!