摘要:類實(shí)際上是中中的緩存類,目的是節(jié)省內(nèi)存消耗,提高程序性能。而當(dāng)堆內(nèi)存中的對象存儲非常多時(shí),就有可能造成內(nèi)存泄漏。使用頻率高創(chuàng)建對象也就越多,堆內(nèi)存中的對象也就越多,所以也就會可能發(fā)生上述中的內(nèi)存溢出等問題。
面試題:問以下代碼輸出的結(jié)果是多少?
public class IntegerTest { @Test public void test() { Integer a = 127; Integer b = 127; System.out.println(String.format("運(yùn)行結(jié)果:%s", a == b)); a = 128; b = 128; System.out.println(String.format("運(yùn)行結(jié)果:%s", a == b)); } }
如果不仔細(xì)看上面的代碼,那么我想很多人都會很快的說出運(yùn)行的結(jié)果。但如果仔細(xì)查看代碼,卻不知道上述代碼中的要考察的相關(guān)知識時(shí),我想也不一定能準(zhǔn)確說出正確的運(yùn)行結(jié)果。那么下面我們看一下上述代碼的運(yùn)行結(jié)果:
運(yùn)行結(jié)果:true 運(yùn)行結(jié)果:false
你猜對了嗎?為什么上面的代碼顯示的結(jié)果居然是不一樣的呢?下面我們詳細(xì)分析一下上述代碼主要考察的知識點(diǎn)。
上述代碼主要考察的是Java中Integer包裝類對象的知識。但在這里有一個(gè)很隱性的知識點(diǎn),也就IntegerCache對象。也就是因?yàn)檫@個(gè)對象的存在才導(dǎo)致上述代碼中運(yùn)行的結(jié)果不一致的。下面我們來了解一下Java中IntegerCache對象的知識。
IntegerCache
IntegerCache類實(shí)際上是Java中Integer中的緩存類,目的是節(jié)省內(nèi)存消耗,提高程序性能。因?yàn)槲覀冎溃贘ava中每創(chuàng)建一個(gè)對象,都會將對象存儲在堆內(nèi)存中。而當(dāng)堆內(nèi)存中的對象存儲非常多時(shí),就有可能造成內(nèi)存泄漏。而在我們?nèi)粘5捻?xiàng)目開發(fā)中我們使有用Integer類型的頻率非常高。使用頻率高創(chuàng)建對象也就越多,堆內(nèi)存中的對象也就越多,所以也就會可能發(fā)生上述中的內(nèi)存溢出等問題。所以Java為了解決上述問題。于是設(shè)計(jì)了IntegerCache類,看名字就知道IntegerCache是個(gè)緩存類,既然是緩存類,目的就是可以將相關(guān)的數(shù)據(jù)緩存下來,這里的數(shù)據(jù)指的就是Integer類的值。也就是上述代碼中的等于右邊的數(shù)值。那既然IntegerCache類可以緩存數(shù)字,為什么上述代碼中的結(jié)果不一樣呢?這個(gè)原因就是IntegerCache類有一個(gè)緩存范圍。IntegerCache類緩存的數(shù)據(jù)范圍為是-128到127之間。所以上述代碼中前兩行代碼中輸出結(jié)果為true(127在IntegerCache類緩存的數(shù)據(jù)范圍內(nèi),于是將127緩存起來,當(dāng)程序在使用這個(gè)127數(shù)字時(shí),因?yàn)榫彺嬷幸呀?jīng)有了,于是直接使用緩存中的127,所以結(jié)果為true),而后二行代碼輸出的結(jié)果為false(超出IntegerCache類的緩存范圍,于是不能緩存,所以創(chuàng)建了新的對象,既然是新的對象結(jié)果顯然是false)。
為了驗(yàn)證我們上述我說的,我們看一下IntegerCache類的底層實(shí)現(xiàn)。下面為源碼:
/** * 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 {@code -XX:AutoBoxCacheMax=} 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) { try { 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); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
看源碼中的注釋我們知道,我們可以通過Jvm中的AutoBoxCacheMax參數(shù)來重新設(shè)置IntegerCache類的緩存范圍。并且我們知道IntegerCache類使用了Integer cache[] 數(shù)據(jù)緩存數(shù)值。
這就是上述面試題中所要考察的相關(guān)知識,實(shí)際上除IntegerCache類之外,在Java中還提供了ByteCache、ShortCache、LongCache、CharacterCache等緩存對象,其中前三個(gè)緩存對象的緩存范圍都是-128 到 127。而CharacterCache緩存對象則是0到127。這就是Java中IntegerCache類相關(guān)的知識,如有考慮不周,或者輸寫有誤的地方,歡迎留言,謝謝。
原文鏈接:http://jilinwula.com/article/...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69473.html
摘要:整型對象在內(nèi)部實(shí)現(xiàn)中通過使用相同的對象引用實(shí)現(xiàn)了緩存和重用。這種緩存策略僅在自動裝箱的時(shí)候有用,使用構(gòu)造器創(chuàng)建的對象不能被緩存。行的結(jié)果為而行則為。所以行的結(jié)果為而行為。中其他類似的緩存的緩存上限可以通過虛擬機(jī)參數(shù)修改,的緩存則沒法修改。 Java5為Integer的操作引入了一個(gè)新的特性,用來節(jié)省內(nèi)存和提高性能。整型對象在內(nèi)部實(shí)現(xiàn)中通過使用相同的對象引用實(shí)現(xiàn)了緩存和重用。上面的規(guī)則默...
摘要:基礎(chǔ)系列的與方法類初始化順序線程池如何彈性伸縮的幾個(gè)要點(diǎn)的緩存什么場景下使用阻塞隊(duì)列的使用及模式中的序本文主要簡述的緩存。而如果大于或小于則它所指向的對象將符合垃圾回收的條件使用,在模式下,使用參數(shù)即可將的自動緩存區(qū)間設(shè)置為。 Java基礎(chǔ)系列 Java的hashcode與equals方法 Java類初始化順序 ThreadPoolExecutor線程池如何彈性伸縮 HashMap的...
摘要:先看下這段神奇的代碼執(zhí)行結(jié)果那么到底做了什么神奇的事情呢先看代碼所以這個(gè)例子其實(shí)包含了中整型類型的一個(gè)知識點(diǎn)。最后打印出來的值,實(shí)際上是的返回值。只有當(dāng)輸入?yún)?shù)不在區(qū)間內(nèi),才執(zhí)行代碼,基于輸入?yún)?shù)創(chuàng)建一個(gè)新的實(shí)例。 先看下這段神奇的Java代碼: public static void main(String[] args) throws Exception { doSom...
摘要:昨晚與一同事聊天,他正在找工作,讓我問他點(diǎn)常見面試題,然后發(fā)現(xiàn)他對的實(shí)現(xiàn)原理不是太清楚,他錯誤地以為只要不超過范圍的兩個(gè)對象就能用進(jìn)行比較,但其實(shí)并不是這樣的這里先上一個(gè)例子運(yùn)行結(jié)果如下下面說一下,原理實(shí)現(xiàn)內(nèi)部有一個(gè)靜態(tài)變量池存放了一個(gè) 昨晚與一同事聊天,他正在找工作,讓我問他點(diǎn)常見面試題,然后發(fā)現(xiàn)他對Integer, Long, BigDecimal的實(shí)現(xiàn)原理不是太清楚,他錯誤地以為...
摘要:還有需要注意的一點(diǎn)是,此類緩存行為不僅存在于對象。還存在于其他的整數(shù)類型,,,。但是能改變緩存范圍的就只有了。 前言 最近跟許多朋友聊了下,在這個(gè)跳槽的黃金季節(jié),大家都有點(diǎn)蠢蠢欲動,所以最近就多聊聊面試的時(shí)候需要注意的一些問題,這些問題不一定多深奧,多復(fù)雜,但是一不注意的話卻容易掉坑。下面看一下面試的時(shí)候經(jīng)常遇到的一段代碼: public class IntegerDemo { ...
閱讀 2627·2021-11-17 17:00
閱讀 1876·2021-10-11 10:57
閱讀 3748·2021-09-09 11:33
閱讀 917·2021-09-09 09:33
閱讀 3555·2019-08-30 14:20
閱讀 3321·2019-08-29 11:25
閱讀 2803·2019-08-26 13:48
閱讀 743·2019-08-26 11:52