資料型別之Integer與int
阿新 • • 發佈:2018-11-08
資料型別之Integer與int
Java入門基本資料型別
眾所周知,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);
//true
Integer i3 = 500;
Integer i4 = 500;
System.out.println(i3 == i4);
//false
System.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 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;
}
基本型別對應的緩衝池如下:
- 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