JAVA反射機制及應用例子

JAVA 反射機制是Java 被視爲動態(或準動態)語言的一個關鍵性質。這個機制允許程式在運行時通過Reflection APIs 取得任何一個已知名稱的class 的內部資訊,包括其modifiers(諸如public, private,static 等等)、superclass(例如Object)、interfaces(例如Cloneable),也包括fields 和methods 的所有資訊, 並在運行時調用任意一個對象的方法;生成動態代理。下面以一段代碼來看一下主要的Reflection APIs,代碼中有相應的註釋。
 

Java代碼 :

import java.lang.reflect.Array; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
 
public class Goods 
{ 
    private String id; 
    private double price; 
 
    public Goods(){ 
        System.out.println("it is a pen"); 
    } 
     
    public Goods(String s1,String s2){ 
        System.out.println(s1+"*"+s2); 
    } 
     
    public String getId() 
    { 
        System.out.println(id); 
        return id; 
    } 
    public void setId(String id) 
    { 
        this.id = id; 
    } 
    public String addName(String str1,String str2){ 
        return str1+str2; 
    } 
    /**
     * @throws ClassNotFoundException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws NoSuchMethodException 
     * @throws SecurityException 
     * @throws InvocationTargetException 
     * @throws IllegalArgumentException 
     * @throws NoSuchFieldException 
     * @功能描述  
     * @輸入參數  
     * @反饋值    
     */ 
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException 
    { 
        // TODO Auto-generated method stub 
        String str = "com.xtlh.sinye.Goods"; 
        Class c = Class.forName(str); 
        Object obj = c.newInstance();//初始化一個Goods的對象 
         
        /**
         * //這裏設置屬性的值 調用setId()方法,類型用Class[],參數用Object[]
         */ 
        Method m = c.getMethod("setId",new Class[]{Class.forName("java.lang.String")});  
        m.invoke(obj,new Object[]{"it's apple"});  
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //這裏是裏獲取屬性的值 調用getId()方法
         */ 
        m = c.getMethod("getId",new Class[]{});  
        m.invoke(obj,new Object []{});  
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //獲得類中聲明的方法
         */ 
        Method me[] = c.getDeclaredMethods();  
        for(int i=0;i<me.length;i++){ 
            System.out.println("method["+i+"]="+me[i].toString()); 
        } 
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //模擬 instanceof 操作符
         */ 
        boolean b1 = c.isInstance(new Integer(34)); 
        System.out.println("Goods is a instance of Integer ? "+b1); 
        boolean b2 = c.isInstance(new Goods());//這裏調用了無參的構造方法 
        System.out.println("Goods is a instance of Goods ? "+b2); 
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //找出類的方法,類的名稱,類的方法的參數,類的方法的返回類型
         */ 
        Method med[] = c.getDeclaredMethods();  
        Method med1[] = c.getMethods();//從字面意思可以看出來,這裏找到所有的方法,即可以找到繼承來的方法等 
        for(int i=0;i<med.length;i++){ 
            Method mee = med[i]; 
            System.out.println("method # "+i+" name="+mee.getName()); 
            System.out.println("declaring class ="+mee.getDeclaringClass()); 
            //方法的參數類型 
            Class pvec[] = m.getParameterTypes(); 
            for(int j=0;j<pvec.length;j++){ 
                System.out.println("parameter # "+j+" ="+pvec[j]); 
            } 
            //方法的異常 
            Class evec[] = m.getExceptionTypes();    
            for (int j = 0; j < evec.length; j++){ 
                System.out.println("exception #" + j + " " + evec[j]);    
            }    
            //方法的返回類型 
            System.out.println("return type = " + mee.getReturnType());  
        } 
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //獲取類的構造函數
         */ 
        Constructor ctorlist[] = c.getDeclaredConstructors();  
        for(int i=0;i<ctorlist.length;i++){ 
            Constructor cons = ctorlist[i]; 
            System.out.println("Constructor #"+i+" name="+cons.getName()); 
            Class[] consParaType = cons.getParameterTypes();//獲得構造函數的參數類型 
            if(consParaType.length==0){ 
                System.out.println("Constructor have no parameters"); 
            }else{ 
                for(int j=0;j<consParaType.length;j++){ 
                    System.out.println("Constructor Parameter type #"+j+" name="+consParaType[j]); 
                } 
            } 
        } 
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //獲取類的屬性
         */ 
        Field fieldlist[] = c.getDeclaredFields();    
        for(int i=0;i<fieldlist.length;i++){ 
            Field field = fieldlist[i]; 
            System.out.println("Filed #"+i+" name="+field.getName());//屬性名稱 
            System.out.println("Filed #"+i+" type="+field.getType());//屬性類型 
             
            int mod = field.getModifiers();  
            System.out.println("modifiers = " + Modifier.toString(mod));//屬性的修飾符 private/public/protected 
        } 
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //根據方法的名稱來執行方法
         */ 
        Class cls = Class.forName("com.xtlh.sinye.Goods");    
        Class partypes[] = new Class[2];    
        partypes[0] = String.class;//更多類型 Long.TYPE Integer.TYPE,或者使用Long.class、Integer.class 
        partypes[1] = Class.forName("java.lang.String");    
        Method meth = cls.getMethod("addName", partypes);    
        Goods goods = new Goods();    
        Object arglist[] = new Object[2];    
        arglist[0] = new String("love");    
        arglist[1] = new String("grape");    
        Object retobj = meth.invoke(goods, arglist);    
        String retval = (String) retobj;    
        System.out.println(retval);  
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * 創建對象,根據指定的參數類型找到相應的構造函數並執行它,以創建一個新的對象實例。使用這種方法可以在程序運行時動態地創建對象,而不是在編譯的時候創建對象,這一點非常有價值
         */ 
        Class clss = Class.forName("com.xtlh.sinye.Goods");    
        Class partypess[] = new Class[2];    
        partypess[0] = String.class;    
        partypess[1] = String.class;    
        Constructor ct = clss.getConstructor(partypess);    
        Object arglists[] = new Object[2];    
        arglists[0] = new String("hello");    
        arglists[1] = new String("orange");    
        Object retobjs = ct.newInstance(arglists);  
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //改變屬性的值
         */ 
        Class ccc = Class.forName("com.xtlh.sinye.Goods");  
        Field fld = ccc.getDeclaredField("price");    
        Goods goods1 = new Goods();    
        System.out.println("price = " + goods1.price);    
        fld.setDouble(goods1, 25.0);    
        System.out.println("price = " + goods1.price);    
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //簡單使用數組,創建了 10 個單位長度的 String 數組,爲第 5 個位置的字符串賦了值,最後將這個字符串從數組中取得並打印了出來
         */ 
        Class cla = Class.forName("java.lang.String");    
        Object arr = Array.newInstance(cla, 10);    
        Array.set(arr, 5, "hello Watermelon");    
        String s = (String) Array.get(arr, 5);    
        System.out.println(s);    
        System.out.println("---------------------------------------------------------------------"); 
         
        /**
         * //複雜數組使用,例中創建了一個 5 x 10 x 15 的整型數組,併爲處於 [3][5][10] 的元素賦了值爲 37。注意,多維數組實際上就是數組的數組,例如,第一個 Array.get 之後,arrobj 是一個 10 x 15 的數組。進而取得其中的一個元素,即長度爲 15 的數組,並使用 Array.setInt 爲它的第 10 個元素賦值。
            注意創建數組時的類型是動態的,在編譯時並不知道其類型。
         */ 
        int dims[] = new int[]{5, 10, 15};    
        Object array = Array.newInstance(Integer.TYPE, dims);    
        Object arrobj = Array.get(array, 3);    
        Class cl = arrobj.getClass().getComponentType();    
        System.out.println(cl);    
        arrobj = Array.get(arrobj, 5);    
        Array.setInt(arrobj, 10, 37);    
        int arrcast[][][] = (int[][][]) array;    
        System.out.println(arrcast[3][5][10]);    
    } 
 
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章