1. 程式人生 > >thinking in java (八) ----- 陣列(Array)

thinking in java (八) ----- 陣列(Array)

一般來說,程式會產生新的物件,有的時候只能到執行期,才能具體知道產生了多少物件,為了存放這些物件的存放(或者說是reference的存放),程式設計師必須提供物件的存放容器

陣列(Array)

陣列是java用來存放以及隨機訪問一連串物件的各種做法中,最有效率的一種。陣列是簡單的線性序列,其中元素能夠被快速訪問,不過缺點是:當你產生陣列後,你不能改變其size。在java中,陣列是一個比較特殊的物件

public class Main{
	public static void main(String[] args) {
		int[] a = new int [10];
		System.out.println(a.getClass().getSuperclass());
		System.out.println(a.getClass().getName());
	}
	
	
}
————————————————————
class java.lang.Object
[I

可以看出Array是Object的直接子類,但是又與一般的java物件有所不同。可以看出其類名是[I,非常滴奇怪,

下面我們再看

public class Main{
	public static void main(String[] args) {
		 System.out.println("Object[]:" + Object[].class);
	        System.out.println("Object[][]:" + Object[][].class);

	        System.out.println("Object:" + Object.class);
	}
	
	
}
++++++++++++++++++++
Object[]:class [Ljava.lang.Object;
Object[][]:class [[Ljava.lang.Object;
Object:class java.lang.Object

從這個例項中我們可以看出陣列類和一般java類是不同的,普通的java類是全限定路徑名+名字作為自己的唯一標識,但是陣列是以[+L+陣列元素類全限定路徑+類名來作為自己的唯一標識,多了[和L

看下面一組程式碼:

public class Main{
	public static void main(String[] args) {
		int[] a = new int [10];
		System.out.println(a.getClass().getName());
		
		int[][] a1 = new int [10][10];
		System.out.println(a1.getClass().getName());
	}
	
	
}
++++++++++++++++++++++++++
[I
[[I

通過這個例子我們知道,[代表一維,[[代表二維。可以簡單滴說陣列的類名由若干個[和"I"組成,下面使用反射機制看一下。

public class Main{
	public static void main(String[] args) {
		int a [] =new int [10];
		Class  myClass = a.getClass();
		System.out.println(myClass.getDeclaredFields().length);
		System.out.println(myClass.getDeclaredMethods().length);
		System.out.println(myClass.getDeclaredAnnotations().length);
		System.out.println(myClass.getDeclaredConstructors().length);
		System.out.println(myClass.getDeclaredClasses().length);
		System.out.println(myClass.getSuperclass());
	 
	}	
}
++++++++++++++++
0
0
0
0
0
class java.lang.Object

可見, [I這個直接子類自身沒有申明任何成員方法,構造方法,成員變數,註解等。可以說這就是一個空類。但是我們經常使用.lenth來檢視陣列的長度,那麼為為甚沒有length這個成員方法呢。先不管這length,先搞清楚[I在哪申明的吧。

首先[I不是一個識別符號,那麼這個類肯定是在程式碼中顯式地申明瞭,只能是在JVM自己執行的時候生成的、java虛擬機器這本書中寫到:

類載入器先看看陣列類是否已經建立,如果建立了就無需建立,如果沒有就建立一個,

如果陣列是引用型別元素的話,那麼類載入器首先去載入元素的類

JVM根據元素型別和唯獨,建立相應的類

因此,是JVM動態地生成了[I類,再想想,JAVA陣列中的元素型別,數量都是未知的,因此必須是動態生成陣列類。

為了研究length是怎麼來的,我們看下一段程式碼。

public class Main{
	public static void main(String[] args) {
		int a [] =new int [10];
		int i = a.length;
		
	 
	}	
}

其位元組碼檔案:

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建立陣列類,應該就是newarray這條指令發出的了。