Java中有8大基本數據類型,它的對應包裝類型以及數據範圍以下:java
基本數據類型名稱 | 封裝數據類型名稱 | 所佔字節數 | 取值範圍 |
---|---|---|---|
boolean | Boolean | 1 | true/false |
byte | Byte | 1 | -128~127 |
char | Character | 2 | 0~65535 |
short | Short | 2 | -32768~32767 |
int | Integer | 4 | -2的31次方到2的31次方-1 |
long | Long | 8 | 2的63次方到2的63次方-1 |
float | Float | 4 | 3.402823e+38 ~ 1.401298e-45 |
double | Double | 8 | 1.797693e+308~ 4.9000000e-324 |
具體的字節數能夠經過Character.SIZE,Double.SIZE等方法進行查看所佔bit位,除以8就是所佔字節數。web
值得一提的是Float.MIN_VALUE以及Double.MIN_VALUE以表示的是Float以及Double所能表示的最小正數,也就是說存在這樣一種狀況,0到±Float.MIN_VALUE之間的值float類型沒法表示,0 到±Double.MIN_VALUE之間的值double類型沒法表示。這並無什麼好奇怪的,由於這些範圍內的數值超出了它們的精度範圍。緩存
在編譯階段,若將原始類型int賦值給Integer類型,就會將原始類型自動編譯爲Integer.valueOf(int),這種叫作裝箱;若是將Integer類型賦值給int類型,則會自動轉換調用intValue()方法,這種叫作拆箱。app
咱們來看一段代碼:大數據
Integer i = new Integer(42);
Integer j = new Integer(42);
System.out.println(i > j ? 1 : i == j ? 0 : -1);//-1
複製代碼
返回的是-1這是爲何呢? 執行i>j的時候會致使自動拆箱,也就是說直接比較它們的基本類型值,比較的結果確定是否認的,那麼接下來就會比較i==j,這裏比較的是對象的引用,返回固然爲false,因此最終結果爲-1.spa
修改方案1:code
int i2 = i;
int j2 = j;
System.out.println(i2 > j2 ? 1 : i2 == j2 ? 0 : -1);
複製代碼
修改方案2:orm
System.out.println(i > j ? 1 : i.intValue() == j.intValue() ? 0 : -1);
複製代碼
先來看一段代碼,關於基本數據類型和封裝類型之間的比較對象
public static void main(String[] args) {
Integer i = 127;
Integer i2 = 127;
int i3 = 127;
Integer j = 128;
Integer j2 = 128;
int j3 = 128;
Integer k = new Integer(127);
Integer k2 = 127;
Integer m = -128;
int m2 = -128;
Integer q = -129;
Integer q2 = -129;
int q3 = -129;
Integer q4 = q3;
System.out.println(i == i2);//true
System.out.println(i == i3);//true
System.out.println(j == j2);//false
System.out.println(j == j3);//true
System.out.println(k == k2);//false
System.out.println(k == i3);//true
System.out.println(m == m2);//true
System.out.println(q == q2);//false
System.out.println(q == q3);//true
System.out.println(q == q4);//false
}
複製代碼
從上面的結果能夠看出了當Integer和int比較的時候,其實是在作拆箱操做,當Integer和
Integer進行比較的時候會發現當值的範圍在-128到127之間比較的時候老是爲true(k==k2這種比較特殊,由於k是new的一個對象),那麼爲何會出現當值在-128在127之間的時候比較總會相等呢?是由於Integer這個類對這個區間的數據作了一個緩存,具體能夠查看JDK源碼:ci
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) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
複製代碼
從上面的代碼能夠看出Integer緩存的結果區間,不錯咱們能夠經過VM參數來修改緩存的High值。
查看源碼能夠看到Byte緩存了(byte)(-128~127)之間的值,Character緩存了(char)(0-127)之間的值,Short緩存了(short)(-128~127)之間的值,Long緩存了(long)(-128~127)之間的值
關於強制轉換,咱們一樣先看一段代碼:
int s = 32768;
System.out.println((short)s);//-32768
複製代碼
結果爲何會這樣呢?由於int是4個字節,也就是32位,而short是2個字節也就是16位,其最高位須要用來表示是正數仍是負數,因此其最大值只有32767。當int轉換爲short的時候高位就被截斷了.
當一個小數據向大數據轉換的時候,系統會自動將其轉換而不用咱們手動添加轉換,這些類型由"小"到"大"分別爲 (byte,short,char)--int--long--float—double。這裏咱們所說的"大"與"小",並非指佔用字節的多少,而是指表示值的範圍的大小。
好比如下的代碼都是編譯經過的
byte b = 12;
int i = b;
long lon = i;
float f = lon;
double d = f;
複製代碼
若是低級類型爲char型,向高級類型(整型)轉換時,會轉換爲對應ASCII碼值,例如
char c='c'; int i=c;
System.out.println("output:"+i);//output:99
複製代碼
對於byte,short,char三種類型而言,他們是平級的,所以不能相互自動轉換,能夠使用下述的強制類型轉換。
short i=99 ; char c=(char)i;
System.out.println("output:"+c);//output:c
複製代碼
因此,高等級的數據類型轉換爲低等級的數據類型的時候必定要慎重,儘可能不去作這種操做