Java中陣列的特性
阿新 • • 發佈:2019-01-06
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 { } }