Java數(shù)據(jù)類型之Cache模式

1、關(guān)于Java數(shù)據(jù)類型

基本數(shù)據(jù)類型

基本數(shù)據(jù)類型有8種,每種基本數(shù)據(jù)類型都有對應(yīng)的引用類型。

類型 描述 長度 可表示數(shù)據(jù) 包裝類型
boolean 布爾型 1 true、false Boolean
byte 字節(jié)型 1 2-7~27-1 Byte
char 字符型 2 2-15~215-1 Character
short 短整型 2 2-15~215-1 Short
int 整型 4 2-31~231-1 Integer
float 浮點(diǎn)型 4 2-31~231-1 Float
long 長整型 8 2-63~263-1 Long
double 雙精度浮點(diǎn)型 8 2-63~263-1 Double

為什么要有包裝類型?

因?yàn)镴ava是面向?qū)ο笳Z言,很多地方用到的是對象,而不是基本數(shù)據(jù)類型。比如集合類中,我們是無法定義集合的泛型是基本數(shù)據(jù)類型的。而包裝類,顧名思義,就是將基本數(shù)據(jù)類型包裝起來,使其具備了對象的性質(zhì),也為其添加了很多操作方法。

自動(dòng)裝箱與拆箱

自動(dòng)裝箱: 就是將基本數(shù)據(jù)類型自動(dòng)轉(zhuǎn)換成對應(yīng)的包裝類。

自動(dòng)拆箱:就是將包裝類自動(dòng)轉(zhuǎn)換成對應(yīng)的基本數(shù)據(jù)類型。

為什么要有自動(dòng)裝拆箱呢?因?yàn)楹芏嗟胤蕉际切枰溥M(jìn)行轉(zhuǎn)換的,而重復(fù)操作又會(huì)顯得很多余,所以為其提供了自動(dòng)適配功能。

那么哪些地方能用到呢?舉兩個(gè)最常用的例子。

  1. 類型轉(zhuǎn)換
Integer i = 10; // 自動(dòng)裝箱
int a = i; // 自動(dòng)拆箱

2)存入集合

List<Integer> list = new ArrayList<Integer>();
int a = 1;
list.add(a); // 自動(dòng)裝箱

2、Cache

顧名思義,Cache就是緩存的意思。那數(shù)據(jù)類型里面哪些地方用到Cache呢?它具備什么作用?

首先拋出一道題,請大家參考。

Integer a = Integer.valueOf(20);
Integer b = Integer.valueOf(20);
System.out.println(a == b);

結(jié)果相等嗎?是相等的。輸出true。

Integer a = Integer.valueOf(128);
Integer b = Integer.valueOf(128);
System.out.println(a == b);

這里結(jié)果不相等的,為啥?128!=128?

首先來看valueOf這個(gè)方法:

  • Integer valueOf(String s, int radix)

將字符串以規(guī)定進(jìn)制轉(zhuǎn)換成Integer,radix表示進(jìn)制數(shù)。

  • Integer valueOf(String s)

將字符串轉(zhuǎn)換為10進(jìn)制的Integer。

  • Integer valueOf(int i)

將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類。

為什么會(huì)造成兩個(gè)相同數(shù)字比較出來不相同呢?來,我們上源碼。

前兩個(gè)方法最終調(diào)用的方法:

    public static Integer valueOf(int i) {
        // 如果值在IntegerCache的低位和高位之間就從IntegerCache里取
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        // 否則new一個(gè)對象
        return new Integer(i);
    }

IntegerCache是Integer中的一個(gè)靜態(tài)內(nèi)部類

private static class IntegerCache {
        // 低位固定為-128
        static final int low = -128;
        // 高位
        static final int high;
        // 存放緩存區(qū)數(shù)據(jù)
        static final Integer cache[];

        static {
            // 高位默認(rèn)為127
            int h = 127;
            // 可以通過配置
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    // 將配置值轉(zhuǎn)換為基本數(shù)據(jù)類型
                    int i = parseInt(integerCacheHighPropValue);
                    // 將配置值與127比較取最大值
                    i = Math.max(i, 127);
                    // 確定高位值,防止數(shù)組長度超過整型最大值
                    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;

            // 初始化數(shù)組大小
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                // 初始化數(shù)組數(shù)據(jù)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            // 如果高位值大于等于127,則拋出異常
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

因?yàn)?28超過了整型緩存區(qū)域,所以每次都會(huì)new一個(gè)對象,所以導(dǎo)致比較出來不相等。

Short、Long、Character等內(nèi)部都有Cache區(qū)域,建議大家多去挖掘挖掘。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容