1. 程式人生 > >Java中陣列的特性

Java中陣列的特性

package com.pansoft.zhangjg.testarray;

public class ArrayTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		test1();
		test2();
		test3();
	}

	/**
	 * 陣列具有這種特性:
	 * 如果有兩個類A和B,如果B繼承(extends)了A,那麼A[]型別的引用就可以指向B[]型別的物件
	 * 測試陣列的特殊特性對引數傳遞的便利性
	 */
	private static void test3() {
		String[] a = new String[3];
		doArray(a);
	}

	private static void doArray(Object[] objs){
		
	}
	
	private static void doArray1(Object obj){
		//不能用Object接收陣列,因為這樣無法對陣列的元素進行訪問
		// obj[1]  //錯誤
		
		//如果在方法內部對obj轉型到陣列,存在型別轉換異常的風險
		// Object[] objs = (Object[]) obj;
	}
	
	private static void doArray2(String[] strs){
		//如果適用特定型別的陣列,就限制了型別,失去靈活性和通用性
	}
	
	private static void doArray3(String name, int age, String id, float account){
		//如果不適用陣列而是依次傳遞引數,會使引數列表變得冗長,難以閱讀
	}
	/**
	 * 測試陣列的整合關係, 並且他的繼承關係是否和陣列中元素的型別有關
	 */
	private static void test2() {
		
		//1		在test1()中已經測試得到以下結論: 陣列也是物件, 陣列的頂層父類是Object, 所以可以向上轉型
		int[] a = new int[8];
		Object obj = a ; //陣列的父類也是Object,可以將a向上轉型到Object
		
		//2		那麼能向下轉型嗎?
		int[] b = (int[])obj;  //可以進行向下轉型
		
		//3		能使用instanceof關鍵字判定嗎?
		if(obj instanceof int[]){  //可以用instanceof關鍵字進行型別判定
			System.out.println("obj的真實型別是int[]");
		}
		
		//4  	下面程式碼成立嗎?
		String[] s = new String[5];
		Object[] obja = s;   //成立,說明可以用Object[]的引用來接收String[]的物件
		
		//5		那麼String[] 的直接父類是Object[] 還是 Object?
		System.out.println(s.getClass().getSuperclass().getName());
		//列印結果為java.lang.Object,說明String[] 的直接父類是 Object而不是Object[]
		
		//6	  下面成立嗎?  Father是Son的直接父類
		Son[] sons = new Son[3];
		Father[] fa = sons;  //成立
		
		//7		那麼Son[] 的直接父類是Father[] 還是  Object[] 或者是Object?
		System.out.println(sons.getClass().getSuperclass().getName());
		//列印結果為java.lang.Object,說明Son[]的直接父類是Object
		
		/**
		 * 做一下總結, 如果A是B的父類, 那麼A[] 型別的引用可以指向 B[]型別的變數
		 * 但是B[]的直接父類是Object, 所有陣列的父類都是Object
		 */
		
		//8		上面的結論可以擴充套件到二維陣列
		Son[][] sonss = new Son[2][4];
		Father[][] fathers = sonss;
		//將Father[][]陣列看成是一維陣列, 這是個陣列中的元素為Father[]
		//將Son[][]陣列看成是一維陣列, 這是個陣列中的元素為Son[]
		//因為Father[]型別的引用可以指向Son[]型別的物件
		//所以,根據上面的結論,Father[][]的引用可以指向Son[][]型別的物件
		
		/**
		 * 擴充套件結論:
		 * 因為Object是所有引用型別的父類
		 * 所以Object[]的引用可以指向任何引用資料型別的陣列的物件. 如:
		 * Object[] objs = new String[1];
		 * Object[] objs = new Son[1];
		 *
		 */
		
		//9		下面的程式碼成立嗎?
		int[] aa = new int[4];
		//Object[] objaa = aa;  //錯誤的,不能通過編譯
		//這是錯誤的, 因為Object不是int的父類,在這裡自動裝箱不起作用
		
		//10 	這樣可以嗎?
		Object[] objss = {"aaa", 1, 2.5};//成立
	}

	/**
	 * 測試在java語言中,陣列是不是物件
	 * 如果是物件, 那麼他的型別是什麼?
	 */
	private static void test1() {
		int[] a = new int[4];
		//a.length;  //對屬性的引用不能當成語句
		int len = a.length;  //陣列中儲存一個欄位, 表示陣列的長度
		
		//以下方法說明陣列可以呼叫方法,java中的陣列是物件.這些方法是Object中的方法,所以可以肯定,陣列的最頂層父類也是Object
		a.clone();
		a.toString();
		
		
		/**
		 * java是強型別的語言,一個物件總會有一個特定的型別,例如 Person p = new Person();
		 * 物件p(確切的說是引用)的型別是Person類, 這個Person類是我們自己編寫的
		 * 那麼陣列的型別是什麼呢? 下面使用反射的方式進行驗證
		 */
		int[] a1 = {1, 2, 3, 4};
		System.out.println(a1.getClass().getName());
		//打印出的陣列類的名字為[I
		
		String[] s = new String[2];
		System.out.println(s.getClass().getName());
		//打印出的陣列類的名字為  [Ljava.lang.String;
		
		String[][] ss = new String[2][3];
		System.out.println(ss.getClass().getName());
		//打印出的陣列類的名字為    [[Ljava.lang.String;
		
		/**
		 * 所以,陣列也是有型別的,只不過這個型別不是有程式設計師自己定義的類, 也不是jdk裡面
		 * 的類, 而是虛擬機器在執行時專門建立的類
		 * 型別的命名規則是:
		 * 		每一維度用一個[表示;
		 * 		[後面是陣列中元素的型別(包括基本資料型別和引用資料型別)
		 * 
		 * 在java語言層面上,s是陣列,也是一個物件,那麼他的型別應該是String[],
		 * 但是在JVM中,他的型別為[java.lang.String
		 * 
		 * 順便說一句普通的類在JVM裡的型別為 包名+類名, 也就是全限定名
		 */
	}
	
	public static class Father {

	}
	
	public static class Son extends Father {

	}
}