【Java反射機制】_Java反射機制的深入研究筆記

來源:互聯網
上載者:User

【Java反射機制】_Java反射機制的深入研究筆記

本章目標:
使用反射調用類中的指定方法
使用反射完成setter及getter方法的調用
使用反射直接操作類中的屬性
使用反射運算元組

3.1、通過反射調用類中的方法

public Method getMethod(String name,Class<?>...parameterTypes)throws NoSuchMethodException,SecurityException
通過getMethod方法得到一個方法的Method對象,之後通過此Method對象來執行方法,但是在方法調用的時候,因為會牽扯到方法中的參數的問題,所以通過getMethod取得的時候,必須設定好需要的參數類型。

package org.lxh.demo15 ;interface China{    // 定義China介面    public static final String NATIONAL = "China" ;    // 定義全域常量    public static final String AUTHOR = "李興華" ;    // 定義全域常量    public void sayChina() ;        // 無參的,沒有傳回值的方法    public String sayHello(String name,int age) ;    // 定義有兩個參數的方法,並返回內容}public class Person implements China{    private String name ;    private int age ;    public Person(){    // 無參構造    }    public Person(String name){        this.name = name ;    // 設定name屬性    }    public Person(String name,int age){        this(name) ;        this.age = age ;    }    public void sayChina(){    // 覆寫方法        System.out.println("作者:" + AUTHOR + ",國籍:" + NATIONAL) ;    }    public String sayHello(String name,int age){        return name + ",你好!我今年:" + age + "歲了!" ;    }    public void setName(String name){        this.name = name ;    }    public void setAge(int age){        this.age = age ;    }    public String getName(){        return this.name ;    }    public int getAge(){        return this.age ;    }};

調用sayChina()方法,因為此方法中沒有任何的參數。
執行調用的方法:

public Object invoke(Object obj,Object... args)throws IllegalAccessException,IllegalArgumentException,InvocationTargetException

執行的時候還需要傳遞參數進去,而且需要執行個體化對象。

package org.lxh.demo15.invokedemo;import java.lang.reflect.Method;public class InvokeSayChinaDemo{    public static void main(String args[]){        Class<?> c1 = null;        try{            c1 = Class.forName("org.lxh.demo15.Person");    //執行個體化Class對象        }catch(Exception e){}        try{            Method met = c1.getMethod("sayChina");    //找到sayChina()方法            met.invoke(c1.newInstance());    //調用方法        }catch(Exception e){            e.printStackTrace();        }    }}

如果現在要調用的方法中存在了參數,則必須設定參數的類型及內容。

package org.lxh.demo15.invokedemo ;import java.lang.reflect.Method ;public class InvokeSayHelloDemo{    public static void main(String args[]){        Class<?> c1 = null ;        try{            c1 = Class.forName("org.lxh.demo15.Person") ;    // 執行個體化Class對象        }catch(Exception e){}        try{            Method  met = c1.getMethod("sayHello",String.class,int.class) ;    // 找到sayChina()方法            String rv = null ;            rv = (String)met.invoke(c1.newInstance(),"李興華",30) ;    // 調用方法            System.out.println(rv) ;        }catch(Exception e){            e.printStackTrace() ;        }    }};

3.2、通過反射調用類setter及getter

Setter及getter方法是一個標準的屬性的存取方法,如果一個類的屬性被封裝,則必須通過setter及getter方法設定和取得,實際上此方法的操作之所以要這樣規定,主要原因是由於反射機制可以給予支援的。
通過反射可以調用setter及getter方法。
如果要想調用setter,例如:name屬性設定,則setName()方法寫,方法的第二個單詞的首字母要大寫。

package org.lxh.demo15.invokedemo ;import java.lang.reflect.Method ;public class InvokeSetGetDemo{    public static void main(String args[]){        Class<?> c1 = null ;        Object obj = null ;        try{            c1 = Class.forName("org.lxh.demo15.Person") ;    // 執行個體化Class對象        }catch(Exception e){}        try{            obj = c1.newInstance() ;        }catch(Exception e){}        setter(obj,"name","李興華",String.class) ;    // 調用setter方法        setter(obj,"age",30,int.class) ;    // 調用setter方法        System.out.print("姓名:") ;        getter(obj,"name") ;        System.out.print("年齡:") ;        getter(obj,"age");    }    /**        Object obj:要操作的對象        String att:要操作的屬性        Object value:要設定的屬性內容        Class<?> type:要設定的屬性類型    */    public static void setter(Object obj,String att,Object value,Class<?> type){        try{            Method met = obj.getClass().getMethod("set"+initStr(att),type) ;    // 得到setter方法            met.invoke(obj,value) ;    // 設定setter的內容        }catch(Exception e){            e.printStackTrace() ;        }    }    public static void getter(Object obj,String att){        try{            Method met = obj.getClass().getMethod("get"+initStr(att)) ;    // 得到setter方法            System.out.println(met.invoke(obj)) ;    // 調用getter取得內容        }catch(Exception e){            e.printStackTrace() ;        }    }    public static String initStr(String old){    // 將單詞的首字母大寫        String str = old.substring(0,1).toUpperCase() + old.substring(1) ;        return str ;    }};
3.3、通過反射調用屬性

如果現在假設要操作一個類中的屬性,則也可以通過Filed完成,則不必麻煩的通過setter及getter。得到公用屬性:
public Field getField(String name) throws NoSuchFieldException,SecurityException
得到本類屬性:
public Field getDeclaredField(String name) throws NoSuchFileException,SecurityException
取得屬性內容:
public Object get(Object obj) throws IlleaglArgumentException,IllegalAccessException
設定屬性內容:
public void set(Object obj,Object value) throws IlleaglArgumentException,IllegalAccessException
在訪問私人屬性的時候,必須讓這個屬性可見:
public void setAccessible(boolean flag) throws SecurityException
將其內容設定成true即可。

package org.lxh.demo15.invokedemo ;import java.lang.reflect.Field ;public class InvokeFieldDemo{    public static void main(String args[]) throws Exception{        Class<?> c1 = null ;        Object obj = null ;        c1 = Class.forName("org.lxh.demo15.Person") ;    // 執行個體化Class對象        obj = c1.newInstance() ;        Field nameField = null ;        Field ageField = null ;        nameField = c1.getDeclaredField("name") ;    // 取得name屬性        ageField = c1.getDeclaredField("age") ;    // 取得name屬性        nameField.setAccessible(true) ;    // 此屬性對外部可見        ageField.setAccessible(true) ;    // 此屬性對外部可見        nameField.set(obj,"李興華") ;    // 設定name屬性內容        ageField.set(obj,30) ;            // 設定age屬性內容        System.out.println("姓名:" + nameField.get(obj)) ;        System.out.println("年齡:" + ageField.get(obj)) ;    }};

但是,觀察,以上的操作中是否需要類的setter及getter方法支援呢?證明以上的操作調用與setter及getter無關,但是為了保證程式的安全性,最好還是通過setter及getter方法完成調用。

3.3、通過反射運算元組

反射機制不光只能用在類中,也可以應該在任意的引用資料類型上,當然,這就包含了數組,數組使用Array類完成。

Class類中存在以下一個方法:
public Class<?> getComponentType()
得到數組指定下標的內容:

public static Object get(Object array,int index) throws IllegalArgumentException,ArrayIndexOutOfBoundsException
修改內容:
public static void set(Object array,int index,Object value) throws IllegalArgumentException,ArrayIndexOutOfBoundsException
開闢新數組:
public static Object newInstance(Class<?> componentType,int ....dimensions) throws IllegalArgumentException,NegativeArraySizeException
取得數組資訊並修改數組內容:

package org.lxh.demo15.invokedemo ;import java.lang.reflect.Array ;public class ChangeArrayDemo{    public static void main(String args[]) throws Exception{        int temp[] = {1,2,3} ;// 聲明一整型數組        int newTemp[] = (int []) arrayInc(temp,5) ;    // 重新開闢空間5        print(newTemp) ;        System.out.println("\n-------------------------") ;        String t[] = {"lxh","mldn","mldnjava"} ;        String nt[] = (String [])arrayInc(t,8) ;        print(nt) ;    }    public static Object arrayInc(Object obj,int len){        Class<?> c = obj.getClass() ;        Class<?> arr = c.getComponentType() ;    // 得到數組的        Object newO = Array.newInstance(arr,len) ;    // 開闢新的大小        int co = Array.getLength(obj) ;        System.arraycopy(obj,0,newO,0,co) ;    // 拷貝內容        return newO ;    }    public static void print(Object obj){    // 數組輸出        Class<?> c = obj.getClass() ;        if(!c.isArray()){    // 判斷是否是數組            return;        }        Class<?> arr = c.getComponentType() ;        System.out.println(arr.getName()+"數組的長度是:" + Array.getLength(obj)) ;     // 輸出數組資訊        for(int i=0;i<Array.getLength(obj);i++){            System.out.print(Array.get(obj,i) + "、") ;    // 通過Array輸出        }    }};
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.