數組對象的類是什麼?
既然數組是對象,那麼數組究竟是什麼呢?當然,不是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這條指令觸發的了。