數據類型之Integer與int
基本數據類型
眾所周知,Java是面向對象的語言,一切皆對象。但是為了兼容人類根深蒂固的數據處理習慣,加快常規數據的處理速度,提供了9種基本數據類型,他們都不具備對象的特性,沒有屬性和行為。Java的9種基本數據類型包括 boolean、byte、char、short、int、long、double和refvar。前8種數據類型表示生活中的真假、字符、整數和小數,最后一種refvar是面向對象世界中的引用變量,也叫引用句柄。此處認為它也是一種基本數據類型。
前8種都有其對應的包裝數據類型,除了char的對應包裝類名為 Character, int為 Integer外,其它所有對應的包裝類名就是把首字母大寫即可。
下面列出了這8種基本數據類型的空間占用大小(bit)及對應的包裝類等信息。
- boolean/1/Boolean
- byte/8/Byte
- char/16/Character
- short/16/Short
- int/32/Integer
- float/32/Float
- long/64/Long
- double/64/Double
包裝類型
前8種基本數據類型都有相應的包裝類,因為Java的設計理念是一切皆是對象,在很多情況下,需要以對象的形式操作,比如hashCode()獲取哈希值,或者getClass獲取類等。包裝類的存在解決了基本數據類型無法做到的事情:泛型類型參數、序列化、類型轉換、高頻區間數據緩存。
重點要說的就是最后一項:緩存池
緩存池
事實上除了Float和Double外,其他包裝類型都會緩存。接下來我以介紹Integer的方式來講解緩存。
先看一段代碼
new Integer(123);
Integer.valueOf(123);
new Integer(123) 與 Integer.valueOf(123) 的區別在于:
- new Integer(123) 每次都會新建一個對象
- Integer.valueOf(123) 會使用緩存池中的對象,多次調用會取得同一個對象的引用。
valueOf() 方法的源碼。
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
如上源代碼,賦值數據i在緩存區間內直接返回緩存池中的Integer對象,否則就會new一個對象。
因此比較時會出現如下問題:
public class TestIntegerCache {public static void main(String[] args) {Integer i1 = 100;Integer i2 = 100;System.out.println(i1 == i2);//trueInteger i3 = 500;Integer i4 = 500;System.out.println(i3 == i4);//falseSystem.out.println(i3.equals(i4));//true}
}
所以推薦所有包裝類型對象之間的比較,全部使用equals方法。
在 Java 8 中,Integer 緩存池的大小默認為 -128~127。
static final int low = -128;
static final int high;
static final Integer cache[];static {// high value may be configured by propertyint 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_VALUEh = 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;
}
基本類型對應的緩沖池如下:
- boolean values true and false
- all byte values
- short values between -128 and 127
- int values between -128 and 127
- char in the range \u0000 to \u007F
相關參考:
StackOverflow : Differences between new Integer(123), Integer.valueOf(123) and just 123