淺淺談Java反射機制( JAVA Reflection)

首先有兩個問題:

 1> 什麼是Java的反射機制?
 2> 反射機制有什麼作用?

<1> 反射機制指的是我們可以於運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。


<2>反射能夠讓我們:

運行時檢測對象的類型;動態構造某個類的對象;檢測類的屬性和方法,並調用;任意調用對象的方法;修改構造函數、方法、屬性的可見性;

用處:

對於Web框架,開發人員在配置文件中定義他們對各種接口和類的實現。通過反射機制,


例如,Spring框架使用如下的配置文件:

<bean id="someID" class="com.programcreek.Foo">
    <property name="someField" value="someValue" />
</bean>

當Spring容器處理元素時,會使用Class.forName(“com.programcreek.Foo”)來初始化這個類,並再次使用反射獲取元素對應的setter方法,爲對象的屬性賦值。

Servlet也會使用相同的機制:

<servlet>
    <servlet-name>someServlet</servlet-name>
    <servlet-class>com.programcreek.WhyReflectionServlet</servlet-class>
<servlet>

介紹三個對象的機制與實現:

類對象(Class類的某一個具體類對象)
實例化對象(某一具體類的實例對象)


a. Class對象的機制與實現(假設已經存在普通類Book)

Class就是類的類型。IntegerString...這些類的類型就是Class
1 三種*類對象*的獲取方式
 Class cl1 (類的類型) = Class.forName("一個類的完整路徑名")
2 類的實例化對象來獲取類對象
 Object ob = new Book();
 Class cl2 (類的類型) = ob.getClass();
3 直接使用類.class
 Class cl3 = Book.class;     

通過類對象可以實例化一個對象

Book bk = (Book)cl1.newInstance();  //默認返回一個Object類的對象,實例化類對象,無參,無參。    

b. Field對象的機制與實現

Java.lang.reflect.Field類,用於表示類中,接口中屬性對象的類。
可以操作類中私有,以及公有等全部屬性和屬性的信息。

package com.java.test;

import com.java.bean.Book;

import java.lang.reflect.Field;

public class TestField {

    //使用傳遞過來的Class對象獲取類中的屬性
    public void show(Class cls){

        //數組中每一個Field對象都是Book的一個屬性
        Field[] fid = cls.getDeclaredFields();       //可以將私有屬性獲取到
        //Field[] fid = cls.getFields();             //只能獲取到公有屬性
        for (Field f : fid){
            System.out.println(f.getName());
            System.out.println(f.getType());
        }
    }

    //該方法使用傳遞過來的實體類對象獲取屬性
    public void show2(Object obj){
        Class cls = obj.getClass();      //獲取類對象,感覺還是回到了第一種方式
        Field[] fid = cls.getDeclaredFields();
        for (Field fi : fid){
            try {
                fi.setAccessible(true);   //可以理解爲啓用私有屬性的訪問權限
                System.out.println(fi.getName()+"值: "+fi.get(obj));//get是將屬性值取出來
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Book bk = new Book();
        bk.setId(1);
        bk.setName("JVM虛擬機");
        bk.setType("Java");

        TestField tf = new TestField();
        //tf.show(Book.class);
        tf.show2(bk);
    }
}

c. Method對象的機制與實現
Java.lang.reflect.Method類是用於表示類中,接口中方法對象的類。
可以操作類中私有,以及公有…全部方法。

package com.java.test;

import com.java.bean.Book;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class TestMethod {

    //該方法用於獲取對象的所有方法名稱 返回值類型 以及參數信息
    public void show(Object obj){
        Class cls = obj.getClass();
        Method[] me = cls.getDeclaredMethods();  //獲取到Book類中所有的方法
        for (Method m : me){
            System.out.println("Name: "+m.getName());           //方法名
            System.out.println("Type: "+ Modifier.toString(m.getModifiers()));      //方法修飾符
            System.out.println("Return: "+m.getReturnType());   //方法返回值
            Class[] praType = m.getParameterTypes();            //獲取方法參數
            System.out.println("params: ");
            for (Class c : praType){
                System.out.println(c.getName());
            }
        }

        try {
            Method mt = cls.getMethod("getName",null);   //獲取到方法後進行調用
            try {
                //此處如果有多個參數的話,先把參數保存在數組(數組可以爲Object類型)裏。
                mt.invoke(obj,new Object[0]);   //obj對象調用getName()方法,參數爲null(有點反射的意思了呦)
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Book bk = new Book();
        bk.setId(1);
        bk.setName("JVM虛擬機");
        bk.setType("Java");

        TestMethod tm = new TestMethod();
        tm.show(bk);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章