JAVA中關於數組的深入

  數組對象的類是什麼?

既然數組是對象,那麼數組究竟是什麼呢?當然,不是java.util.Arrays

public class TestArray {

        private class Dog {

        }

        public static void main(String[] args) {

           int a[] = new int[10];

           int b[] = new int[5];

           //Dog a[][] = new Dog[2][];//[[LTestArray$Dog;

           //int a[][][] = new int[2][][];//[[[I

           //long a[][] = new long[10][];//[[J

           //float a[] = new float[2];//[F

     //String a[][] = new String[10][];

//[[Ljava.lang.String;

           Class clazz = a.getClass();

           System.out.println(clazz.getName());

           Class clazzb = b.getClass();

           System.out.println(clazzb.getName());

        }

}

根據上面的實例,可以得出結論:

ü  數組的類名由若干個’[‘和數組元素類型的內部名稱組成,’[‘的數目代表了數組的

維數;

ü  具有相同類型元素和相同維度的數組,屬於同一個類,如果兩個數組的元素類型相

同,但維度不同那麼它們也不屬於同一個類,如果一個數組的元素類型和維度相同,但長度不同,那麼他們還是屬於同一個類;

(2) 數組的類有哪些成員?

實例測試:

public class TestArray {

        private class Dog {

        }

        public static void main(String[] args) {

           int a[] = new int[10];

           Class clazz = a.getClass();

       System.out.println(clazz.getName());

       System.out.println(clazz.getDeclaredFields().length);

       System.out.println(clazz.getDeclaredMethods().length);

    System.out.println(clazz.getDeclaredConstructors().length);

System.out.println(clazz.getDeclaredAnnotations().length);

       System.out.println(clazz.getDeclaredClasses().length);

       System.out.println(clazz.getSuperclass());

        }

}

打印結果:

[I

0

0

0

0

0

class java.lang.Object

    可見,[I這個類是java.lang.Object的直接子類,自身沒有聲明任何成員變量、成員方法、構造函數和Annocation,可以說:[I就是一個空類。學到這裏,我們起碼會產生這樣一個疑問:爲什麼連length這個成員變量都沒有呢?因爲我們經常使用數組.length來獲得數組的長度,編譯器怎麼就沒有報錯了?

  數組的類在哪裏聲明?

類加載器先看看數組類是否已經被創建了。如果沒有,那就說明需要創建數組類;如果有,那就無需創建了。

如果數組元素是引用類型,那麼類加載器首先去加載數組元素的類。

JVM根據元素類型和維度,創建相應的數組類。

可見,是JVM自己在運行時生成了數組的類對象;再細想,JVM必須動態生成數組類,因爲JAVA數組類的數量和元素類型、維度(最多255)有關,可見是無法預先聲明好的。

  沒有length這個成員變量!

我們已經發現, JVM沒有爲數組類生成length這個成員變量,那麼Array.length這樣的語法如何通過編譯,如何執行的呢?

讓我們看看字節碼吧!編寫一段最簡單的代碼,使用jclasslib查看字節碼。

1.public class Main {  

2.    public static void main(String[] args) {  

3.    int a[] = new int[2];  

4.        int i = a.length;  

5.    }  

6.} 

使用SUN JDK 1.6編譯上述代碼,並使用jclasslib打開Main.class文件,得到main方法的字節碼:

0 iconst_2          //int型常量2壓入操作數棧

1 newarray 10 (int) //2彈出操作數棧,作爲長度,創建一個元素類型爲int, 維度爲1的數組,並將數組的引用壓入操作數棧

3 astore_1     //將數組的引用從操作數棧中彈出,保存在索引爲1的局部變量 (a)

4 aload_1           //將索引爲1的局部變量(a)壓入操作數棧

5 arraylength  //從操作數棧彈出數組引用(a),並獲取其長度(JVM負責實現如何

           //獲取),並將長度壓入操作數棧

6 istore_2     //將數組長度從操作數棧彈出,保存在索引爲2的局部變量(i)

7 return       //main方法返回

    可見,在這段字節碼中,根本就沒有看見length這個成員變量,獲取數組長度是由一條特定的指令arraylength實現(怎麼實現就不管了,JVM總有辦法)。編譯器對Array.length這樣的語法做了特殊處理,直接編譯成了arraylength指令。另外,JVM創建數組類,應該就是由newarray這條指令觸發的了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章