閱讀862 返回首頁    go 阿裏雲 go 技術社區[雲棲]


反射中的Constructor和數組反射

一、反射中的Constructor

Constructor類代表某個類中的一個構造方法

        Constructor 翻譯過來的意思是"構造函數",它是用來描述一個類中的構造函數的。JDK幫助文檔的解釋--->Constructor 提供關於類的單個構造方法的信息以及對它的訪問權限。

現在我有一個MyConstructor類,用反射分別打印出1,2,3.  

public class MyConstructor {// --------------------------------------1
    public MyConstructor(){
        System.out.println("1");
    }
    public MyConstructor(int i){//--------------------------------------2
        System.out.println("2");
    }
    public MyConstructor(int i,String s){//---------------------------3
        System.out.println("3");
    }
}

下麵我們現在打印出一個1

public static void main(String[] args) throws Exception{

      //截的圖是JDK幫助文檔裏麵的解釋
       
        Constructor myConstructor1 = MyConstructor.class.getConstructor();//這裏得到的是標記為1的構造函數(相關知識點方法的重載)

       
        myConstructor1.newInstance();
        //上麵的2句話輸出結果為1.

        Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class);//這裏得到的是標記為2的構造函數(相關知識點方法的重載)
        //開始由於受到反射invoke()的思想,並且沒有看幫助文檔對newInstance()的解釋,然後我直接寫了下麵的語句
        myConstructor1.newInstance(new MyConstructor());//new MyConstructor()我的意思是傳帶有myConstructor1的構造函數方法的對象給它調用(這裏不懂的同學可以看幫 //助文檔Method類中invoke()方法的解釋),好嘛這裏是我弄混淆了

        寫成這樣也是錯的myConstructor1.newInstance(int.class);

        //輸出結果為
       

        //argument type mismatch翻譯過來的意思是:參數類型不匹配

        // 最後寫成這樣就對了

        myConstructor1.newInstance(0);

        //執行輸出的結果為2.

        //打印1和打印2都寫出來了,想必大家打印出3就不難了。

        Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class,String.class);//這裏得到的是標記為3的構造函數(相關知識點方法的重載)
        myConstructor1.newInstance(0,"a");

        //執行輸出的結果為3

    }


二、數組反射

     在jdk幫助文檔中的Class介紹有這樣的話:

什麼意思呢?意思就是說如果有2個數組對象,它們具有相同的元素類型和維數的話,那它們的class(在內存中的字節碼)也是相同的。

示例代碼一:

public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
        System.out.println(a1==a2);//類型相等,維度相等
        //System.out.println(a1==a4);//類型不等,維度相等--------這句編譯報錯
        //System.out.println(a1==a3);//類型相等,維度不等--------這句編譯報錯
    }

輸出為:false

咦~~~怎麼會是false呢,明明類型相等,維度相等,那為什麼還是false呢?後麵突然發現a1 == a2比的是對象,它們的內容不相等,所以為false。最後改成下麵的正確代碼:

public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
        
        System.out.println(a1.getClass()==a2.getClass());//類型相等,維度相等
        System.out.println(a1.getClass()==a4.getClass());//類型不等,維度相等
        System.out.println(a1.getClass()==a3.getClass());//類型相等,維度不等
    }

這裏大家在看下麵的結果前可以自己先想想

輸出結果為:

true
false
false

在這裏有個小插曲下麵2張圖大家對比下

圖一:

圖二:

細心的你一定發現了哈,二張圖的內容都是一樣的,毫無區別,那為什麼圖二中的內容有編譯不通過的呢?

現在我隻能告訴你圖一的JDK是1.4的,而圖二的JDK是1.6的,關於JDk1.5有興趣的朋友可以改來試試哈,至於為什麼會這樣,具體原因我也說不出來,因為我不知道,嘿嘿~~~~(拿別人的回答來給大家參考參考吧------->“這是編譯報錯,你用的比以前的東西高級了,後麵兩個明顯因為是類型都不對,答案是false的就直接編譯就報錯了再說明白點,編譯器版本高了聰明了,覺得這種問題低級所以不想讓你編譯通過了”對這解釋感覺神忽忽的--!)



好奇的人會嚐試的運行這個代碼:System.out.println(a1.getClass().getName());輸入結果為:[I,什麼意思呢?[:代表是數組,I:代表是int類型。與之相關的介紹在JDK幫助文檔裏麵有解說。


System.out.println(a3.getClass().getName());//int [][] a3 = new int[2][3];
System.out.println(void.class.getName());

上麵兩句分別輸出:

[[I
void

如果是String[][][][][] test = new String[1][2][3][4][5];會輸出什麼?



public static void main(String[] args){
        int [] a1 = new int[3];
        int [] a2 = new int[4];
        int [][] a3 = new int[2][3];
        String[] a4 = new String[3];
    
        System.out.println(a1.getClass().getSuperclass().getName());//getSuperclass()得到父類的class
        System.out.println(a4.getClass().getSuperclass().getName());
        //這2句話輸出分別為java.lang.Object和java.lang.Object(表明a1和a4的父類都一樣)
        //所以
        Object aObj1 = a1;//裏氏替換原則
        Object aObj2 = a4;//裏氏替換原則

        //下麵代碼回報編譯異常
        Object[] aObj3 = a1;//int [] a1 = new int[3];理解為有一個int[]數組,裏麵裝的是int類型,int類型不屬於Object

       
        Object[] aObj4 = a3;//int [][] a3 = new int[2][3];理解為有一個int[]數組,裏麵裝的是int[]類型,int[]類型屬於Object

       
        Object[] aObj5 = a4;//String[] a4 = new String[3];理解為有一個String[]數組,裏麵裝的是String類型,String類型屬於Object 

       
    }



用反射的方式操作數組

我有一個方法public static void print(Object obj){},這方法是用來打印東西的方法,你傳一個對象給我,我就給你打印,這時候問題出現了,你會不會傳一個數組給我呢?答案是會的,但是我又怎麼知道你傳的是數組呢?這時候數組的反射有派上用場了

上代碼:

/**
     * 打印對象
     * @param obj 你傳來的任何對象,如果是數組,打印裏麵的每一個元素
     */
    public static void printObject(Object obj){
        Class clazz = obj.getClass();
        //true:代表是數組,false:代表不是數組
        if (clazz.isArray()) {
            int len = Array.getLength(obj);
            for (int i = 0; i < len; i++) {
                System.out.println(Array.get(obj, i));
            }
            System.out.println("另一種獲取的方法");
            Object[] tempObj = (Object[]) obj;
            for (Object object : tempObj) {
                System.out.println(object);
            }
        }else{
            System.out.println(obj);
        }
    }

      

public static void main(String[] args){

        printObject(a4);
        printObject("hahaha");

}

輸出結果:

a
b
c
另一種獲取的方法
a
b
c
hahaha


有一個Object[] a = new Object[]{"a",1};這時候您是說不清這個a是什麼類型的,說是int它裏麵有String,說是String它裏麵有int,但是可以知道a[0]是什麼類型的,a[1]是什麼類型的,a[0].getClass().getName();


最後更新:2017-04-03 14:54:08

  上一篇:go CWnd *和HWnd轉換
  下一篇:go 計算機體係結構6_緩存結構