(黑色字體代表重點,紅色字體代表不確定對錯)
1、java中的基本數據類型
java是一個近乎純潔的面向對象編程語音,引入基本數據類型是為了編程方便,但是為了能夠將這些基本數據類型當成對象操作,java為每一個基本數據類型引入了對應的包裝類型(wrapper class)。具體如下:
int --- Integer
short --- Short
long --- Long
double --- Double
float --- Float
boolean --- Boolean
byte --- Byte
char --- Character
從java 5 開始引入了自動裝箱/拆箱機制,使得兩者可以相互轉換。
2、基本類型和引用類型的區別。
java中的數據類型分為兩大類:基本數據類型和引用數據類型
基本類型的值就是一個數字,一個字符,或者一個布爾值。存放在棧空間中,未初始化時為隨機值。
引用類型是一個對象類型,值是指向內存空間的引用,就是地址。所指向的內存中保存着變量所表示的一個值或一組值。存放在堆空間中,未初始化時由默認的值,比如int未初始化時為0,boolean未初始化時為false。
基本數據類型,包括數值型,字符型和布爾型。
引用數據類型:類、接口類型、數組類型、枚舉類型、注解類型;
棧的數據大小和生存期都是確定的,特點是其中的數據可以共享,存取速度比對快,僅次於寄存器。主要存放基本類型的變量(byte,short,int,long,float,double,boolean,char)和對象引用。
例如:
int a=1;
int b=1;
以上變量的實現過程可以棧的數據共享,編譯器首先處理a的實現,實現過程是先在棧中查找是否存在值為1的空間,如果有就直接將a指向該空間,如果沒有就會開辟新空間,並把1存進來,因此,在處理b的實現時就會出現a,b都會指向同一個值為1的空間,實現共享。當修改b的值時,過程還是一樣,比如,修改b=2,會查找為2的空間,有則指向,無則,保存。這樣就會有利於空間的充分利用。
其中,String不是基本數據類型,是個引用類型,基礎類型只表示簡單的字符或數字,引用類型可以是任何復雜的數據結構,java虛擬機處理基礎類型與引用類型的方式是不一樣的,對於基本類型,java虛擬機會為其分配數據類型實際占用的內存空間,而對於引用類型變量,他僅僅是一個指向堆區中某個實例的指針。
1 class AutoUnboxingTest { 2 3 public static void main(String[] args) { 4 Integer a = new Integer(3); 5 Integer b = 3; // 將3自動裝箱成Integer類型 6 int c = 3; 7 System.out.println(a == b); // false 兩個引用沒有引用同一對象 8 System.out.println(a == c); // true a自動拆箱成int類型再和c比較 9 } 10 }
1 public class Test03 { 2 3 public static void main(String[] args) { 4 Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150; 5 6 System.out.println(f1 == f2); // true 7 System.out.println(f3 == f4); //false 8 } 9 }
第二段代碼中,第一個輸出為true,第二個輸出為false。
因為f1、f2、f3、f4四個變量都是Integer的對象引用,所以在下面的==運算比較的不是值,而是引用。裝箱的本質就是在給Integer對象賦Int類型的值時,會調用Integer類的靜態方法valueOf,下面是valueOf的源代碼
1 public static Integer valueOf(int i) { 2 if (i >= IntegerCache.low && i <= IntegerCache.high) 3 return IntegerCache.cache[i + (-IntegerCache.low)]; 4 return new Integer(i); 5 }
IntegerCache是Integer的內部類,其代碼如下所示:
1 /** 2 * Cache to support the object identity semantics of autoboxing for values between 3 * -128 and 127 (inclusive) as required by JLS. 4 * 5 * The cache is initialized on first usage. The size of the cache 6 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. 7 * During VM initialization, java.lang.Integer.IntegerCache.high property 8 * may be set and saved in the private system properties in the 9 * sun.misc.VM class. 10 */ 11 12 private static class IntegerCache { 13 static final int low = -128; 14 static final int high; 15 static final Integer cache[]; 16 17 static { 18 // high value may be configured by property 19 int h = 127; 20 String integerCacheHighPropValue = 21 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 22 if (integerCacheHighPropValue != null) { 23 try { 24 int i = parseInt(integerCacheHighPropValue); 25 i = Math.max(i, 127); 26 // Maximum array size is Integer.MAX_VALUE 27 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); 28 } catch( NumberFormatException nfe) { 29 // If the property cannot be parsed into an int, ignore it. 30 } 31 } 32 high = h; 33 34 cache = new Integer[(high - low) + 1]; 35 int j = low; 36 for(int k = 0; k < cache.length; k++) 37 cache[k] = new Integer(j++); 38 39 // range [-128, 127] must be interned (JLS7 5.1.7) 40 assert IntegerCache.high >= 127; 41 } 42 43 private IntegerCache() {} 44 }
如果整型字面量的值在-128到127之間,那么不會new新的Integer對象,而是直接引用常量池中的Integer對象,java中基本類型的包裝類的大部分都實現了常量池技術,這些類是Byte,Short,Integer,Long,Character,Boolean,另外兩種浮點數類型的包裝類則沒有實現。另外Byte,Short,Integer,Long,Character這5種整型的包裝類也只是在對應值小於等於127時才可使用常量池,也即對象不負責創建和管理大於127的這些類的對象。