Java 中的操做數(不知道叫什麼,相對於 bytecode 而言,相似 CPU 的操做碼和操做數)分爲值類型和引用類型:java
值類型就是直接存儲最終數值的,如 char, int, float, double...數組
引用類型包括了數組,以及其它全部用 class 定義的數據類型,這種數據類型由引用和對象實例連部分組成。this
雖然 Java 中一切都是類,可是對於值類型,由於不須要存儲其‘對象’特徵,因此,編譯器只爲他們分配了 stack 上的空間,存儲單個的值就能夠了。而引用類型則不一樣,他們的變量存儲分爲兩部分:在 stack 中的引用(指針),以及在 heap 中的對象實例。大概長這樣(圖借別人的,看最後的連接):spa
使用下面一段代碼來理解這個問題,體會下區別(String.equals() 的標準實現)。指針
1 public boolean equals(Object anObject) { 2 if (this == anObject) { 3 return true; 4 } 5 if (anObject instanceof String) { 6 String anotherString = (String)anObject; 7 int n = value.length; 8 if (n == anotherString.value.length) { 9 char v1[] = value; 10 char v2[] = anotherString.value; 11 int i = 0; 12 while (n-- != 0) { 13 if (v1[i] != v2[i]) 14 return false; 15 i++; 16 } 17 return true; 18 } 19 } 20 return false; 21 }
一塊兒從這段代碼來看看值類型和引用類型的區別:code
1. 第 2 行,首先使用 == 判斷,兩個引用指向的是否爲同一個對象實例。對象
2. 第 5 行,判斷傳入的 object 是不是 String 的實例。blog
3. 第 6 行,將傳入的 object 強制轉換爲 String 類。ip
4. 第 七、8 行,取 this.value.length 與 anotherString.value.length 做比較。value 的類型是 char[],由於數組是一個有限的數據集合,其定義時就已經固定了長度。因此這個操做被編譯後,只是兩個內存單元的內容比較。內存
5. 第 九、10 行,建立新的數組引用,分別指向 this.value 和 anotherString.value。
6. 第 11-16 行,逐個比較兩個 char 數組中的元素。直接比較兩個數組各個元素的效率,是要比比較 String 元素的效率更高的(轉化爲 Char 對象的比較,再比較 Char value,顯然是要耗費更多資源的...)。
關於數組
數組是 JVM 提供的基本數據類型之一。
JVM 直接提供的數組類型有 T_BOOLEAN([Z, 1byte)、T_CHAR([C, 2bytes)、T_FLOAT([F, 4bytes)、T_DOUBLE([D,8bytes)、T_BYTE([B, 1bytes)、T_SHORT([S, 2bytes)、T_INT([I, 4bytes)、T_LONG([J, 8bytes)。
咱們能夠輕鬆驗證,一個數組是 instanceof Object,同時,數組調用方法 getClass().getName(),也是能夠正確輸出的。
public class arrayTest { public static void main(String[] args) { int[] a = {1,2,3,4}; System.out.println(a.getClass().getName()); System.out.println("a is instanceof Object? "+(a instanceof Object)); } }
固然,數組的實現方法是在 JVM 中的,但這並不妨礙咱們像使用其它類/對象同樣類使用數組。
一個 array 在內存中的 layout 大概長這樣:
從上面的圖中,能夠看到兩個信息,第一個,數組在內存中是連續存放的,第二個,header 以後的位置存儲着數組的長度。這也是爲何咱們能夠直接獲取數組的 length 屬性,而其它一些類,必須使用 length() 方法。
關於 length 存儲空間的大小,這個顯示是和 JVM 實現有關的。查閱文檔發現,sun 的 JVM (java7) 版本:32位系統中 size_t 是4字節的,在64位系統中,size_t 是8字節的。
另外,好奇對象數組是怎樣存的,打印了一下 String[] b 的 classNage,顯示是「[Ljava.lang.String;」。其中 「[」 表示這是個數組,「L/java/lang.String;」 叫作 JavaNative Interface Field Descriptors,大概就是說這是個 String 類型的數組了。
建立數組的 bytecode 是 JAVA_NEWARRAY 和 JAVA_ANEWARRAY,暫做記錄,改天有空再看看 JVM 中是怎麼來操做的。