Integer類掌握了多少?
最近看圖靈學院張飛老師的Java架構師課程中講解了一個Integer的面試題,感覺很有深度,難怪命名為一道java面試題,讓你開始懷疑人生。
示例代碼1
不要小看這道題,殺傷力還是蠻高!畢竟是一道陷阱題。我覺得主要是考察大家是否閱讀了Integer包裝類的源碼以及拆箱裝箱問題。裝箱拆箱估計難不倒大家。為什麼說是考察大家閱讀源碼呢?引用這裡面涉及到了一個IntegerCache的問題。默認情況下是-128到127。我們來看下Integer源碼
在Java虛擬機初始化的時候,java.lang.Integer.IntegerCache.high屬性就被設置了,但是我們可以通過VM arg:-XX:AutoBoxCacheMax來進行調整,這個IntegerCache中的cache數組是在方法區的運行常量池中。所以說第一個是true,第二個是false。例如:我設置虛擬機參數為-XX:AutoBoxCacheMax=65535,那麼運行結果是2個true。也從另外一個方面看出,看源碼重要。可以看出越是這麼簡單的面試題,越需要面試者需要相當深厚的功夫才行。
示例代碼2
示例2就更加變態了,來個再熟悉不過的swap方法,是不是有點意外,還可以這樣使來交互2個變數。考察Integer的裝箱拆箱,反射,IntegerCache緩存的字元串常量。值得主要的是如果注釋掉17行,開啟16行,運行結果差異很大,為什麼會出現2個2呢?仔細想想,原來是set方法改變了常量池的值。如果不理解建議看看源碼。
總結
總結一下:對於包裝類型Short Character Long Byte Integer,默認情況下都是在-128-127之間直接從方法區的運行時常量池中拿數據,超出範圍則就是new出來的一個新的在堆區的對象。而對於Double Float則永遠是在堆區new一個對象。對於String類型則是運行時常量池中拿數據。另外對於常量池的改變盡量避免使用反射去改,會出現意向不到的結果。


※札記CAS、AQS、CountDownLatch、CyclicBarrier的原理
TAG:dengyu的博客 |