[toc]html
數據類型的出現是爲了把數據分紅所需內存大小不一樣的數據,合理、有效利用內存。數據類型在計算機語言裏面,是對內存位置的一個抽象表達方式。java
在JAVA語言種將數據類型分爲兩類:基本數據類型
和引用數據類型
面試
基本類型
:簡單數據類型是不能簡化的、內置的數據類型、由編程語言自己定義,它表示了真實的數字、字符和整數。引用數據類型
:Java語言的引用數據類型包括類、接口和數組類型,還有一種特殊的null類型。引用數據類型是對一個對象的引用,對象有兩種:數組和實例(面向對象的基本知識點,這篇文章主要以基本數據類型爲主)基本數據類型分爲4類,分別爲整型、浮點型、字符型和布爾型編程
4種整型量都是有符號的,符號佔一位(byte的取值範圍本該是2的8次方,其餘相似)。數組
下表能夠清楚的看出每一個取值範圍
內可使用的數據類型
(這裏沒有把負數部分畫出來)緩存
取值範圍 | 0~127 | 128 ~ 32767 | 32768 ~ 2147483647 | 2147483648 ~ 9223372...... |
---|---|---|---|---|
數據類型 | byte、short、int、long | short、int、long | int、long | long |
byte b = 127;
byte b2 = 128;//報錯:Required:byte Found:int(默認是int類型)
複製代碼
int num1 = 2147483647;
long l1 = 2147483647;//正常,發生了自動類型轉換
int num2 = 2147483648;//報錯: Integer number too
large
long l2 = 2147483648;//報錯: Integer number too
large
long l3 = 2147483648L;//正常
複製代碼
int num1=013;//八進制
int num2=0x13;//十六進制
複製代碼
重點說明二進制表示方式安全
全部數字在計算機底層都是以二進制形式表示的,原碼是直接將一個數值換算成二進制數。計算機是以補碼形式保存全部的整數。正數的補碼和原碼徹底相同,負數的補碼是原碼的反碼加1;反碼是對原碼按位取反,最高位符號位不變。併發
關於進制間的轉換請看 進制間的轉換 這篇文章編程語言
十進制數形式,float浮點數後加F(或f),double浮點數後加D(或d),浮點數必須包含一個小數點,性能
如float f=5.1200_001f;//可使用_分隔,方便校對數位
科學計數法形式,只有浮點型的數值可使用科學計數法形式表示。如:5.12E2(5.12✖️10^2)
經常使用轉義字符
用於表示邏輯上的」真「或」假「
取值範圍小的類型賦值給取值範圍大的類型,系統自動進行類型轉換,如圖所示,能夠根據箭頭指向發生自動轉換
強制類型轉換可能會丟失精度,因此須要使用()進行類型轉換。
32位int型最高位0表示正數,轉換爲byte類型,高位精度丟失,第8位爲byte最高位,1表示負數,所以正數的int型因丟失精度變成了負數的byte型。
當一個算術表達式中包含多個基本類型的值時,整個算術表達式的數據類型將發生自動提高
System.out.println("Hello" + 'a' + 7);//Helloa7
System.out.println('a' + 7 + "Hello");//104Hello
複製代碼
Java中的int類型在內存中只佔用4個字節,而一個Object對象自己最少佔用8個字節,另外還須要4個字節來引用它。除此以外CPU對基本類型的處理更加高效。
既然如此爲何還須要包裝類?
Java是面向對象的編程語言,但這8種基本數據類型並不支持面試對象的特性。因此 Java 須要一個這樣的包裝類來使其面向對象的完整性,這樣一來基本類型具備了對象的特性,例如:實現可空類型,完成字符串像基本類型的轉換,另外Java 集合中只能放入包裝類型,不支持基本類型。
//可爲空
Integer integer=null;
//字符串轉換爲int型
int num=Integer.valueOf("123");
//java集合只能放入Integer類型,沒法放入int類型
ArrayList<Integer> arrayList=new ArrayList<>();
複製代碼
Integer integer = Integer.valueOf(127);
int intValue = integer.intValue();
複製代碼
private final int value;
//intValue方法比較簡單,直接返回value
public int intValue() {
return value;
}
//valueOf方法的內部實現
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
複製代碼
能夠從valueOf
方法內部看到,傳入進來的i並非直接調用new Integer(i)
來建立對象的,而是經過IntegerCache.cache
緩存中獲取的。
IntegerCache是Integer的一個內部類
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() {}
}
複製代碼
從上面的代碼中,能夠看到IntegerCache類中聲明瞭Integer cache[]
數組來緩存Integer
對象的,而且IntegerCache.low
和IntegerCache.high
常量肯定了cache
的範圍從-128~127,也就是說不在這個範圍內的值,會直接經過new Integer(i)
來建立對象。
Integer num1 = 127;
Integer num2 = 127;
System.out.println(num1 == num2);//引用的同一個對象因此輸出爲 true
Integer num1 = 128;
Integer num2 = 128;
System.out.println(num1 == num2);//超出了緩存範圍輸出false
Integer integer1 = new Integer(127);
Integer integer2 = new Integer(127);
System.out.println(integer1 == integer2);//直接new的對象,未走緩存輸出false
複製代碼
在int和Integer類型之間轉換其實不須要如此的麻煩,從java5開始爲咱們提供了裝箱和拆箱的操做,簡化轉換過程。
Integer a= 123; // 裝箱
int b = a; // 拆箱
複製代碼
裝箱和拆箱能夠當作一種java語法糖,javac編譯器會自動把裝箱轉換爲Integer.valueOf(),把拆箱轉換爲Integer.intValue(),所以咱們在使用裝箱時依然可使用Integer
的緩存。
包裝類的成員變量value
都使用了final
關鍵字修飾,這代表它們是不可變類型(常量)。
對於成員變量value
只須要明白3點就能夠了
pirvate
,因此外部沒法修改它final
關鍵字修飾,內部一旦賦值便沒法再改變String
類型中詳細說明(String
是經過copyOf()
方法來保證不可變的)之因此設計成不可變的的目的是爲了保證基本的信息安全
和併發環境下的線程安全