13.反射原理及示例

自從Jdk1.5推出了反射,java從一種靜態(tài)語言變?yōu)橐环N動(dòng)態(tài)語言了??梢詣?dòng)態(tài)調(diào)用方法的具體方法、實(shí)現(xiàn)等等,一下高端大氣上檔次起來。

1、反射是什么

反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。

2、反射機(jī)制能做什么

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類;
  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;
  • 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;
  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;

3、反射機(jī)制的相關(guān)API及使用

代碼參見com.critc.ReflectTest

/**
 * Created by 孔垂云 on 2017/4/17.
 * 通過一個(gè)對(duì)象獲得完整的包名和類名
 */
public class ReflectTest {

    public static void main(String[] args) throws Exception {
        //通過一個(gè)對(duì)象獲得完整的包名和類名
        ReflectTest testReflect = new ReflectTest();
        System.out.println(testReflect.getClass().getName());
        // 結(jié)果 com.critc.ReflectTest


        //實(shí)例化Class類對(duì)象
        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;
        // 一般采用這種形式
        class1 = Class.forName("com.critc.ReflectTest");
        class2 = new ReflectTest().getClass();
        class3 = ReflectTest.class;
        System.out.println("類名稱   " + class1.getName());
        System.out.println("類名稱   " + class2.getName());
        System.out.println("類名稱   " + class3.getName());


        //獲取某個(gè)類的全部屬性
        Class<?> clazz = Class.forName("com.critc.vo.User1");
        System.out.println("===============本類屬性===============");
        // 取得本類的全部屬性
        Field[] field = clazz.getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
            // 權(quán)限修飾符
            int mo = field[i].getModifiers();
            String priv = Modifier.toString(mo);
            // 屬性類型
            Class<?> type = field[i].getType();
            System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
        }

        //獲取某個(gè)類的全部方法
        Class<?> clazz2 = Class.forName("com.critc.vo.User1");
        Method method[] = clazz2.getMethods();
        System.out.println("==========所有方法如下:=========");
        for (int i = 0; i < method.length; ++i) {
            Class<?> returnType = method[i].getReturnType();
            Class<?> para[] = method[i].getParameterTypes();
            int temp = method[i].getModifiers();
            System.out.print(Modifier.toString(temp) + " ");
            System.out.print(returnType.getName() + "  ");
            System.out.print(method[i].getName() + " ");
            System.out.print("(");
            for (int j = 0; j < para.length; ++j) {
                System.out.print(para[j].getName() + " " + "arg" + j);
                if (j < para.length - 1) {
                    System.out.print(",");
                }
            }
            Class<?> exce[] = method[i].getExceptionTypes();
            if (exce.length > 0) {
                System.out.print(") throws ");
                for (int k = 0; k < exce.length; ++k) {
                    System.out.print(exce[k].getName() + " ");
                    if (k < exce.length - 1) {
                        System.out.print(",");
                    }
                }
            } else {
                System.out.print(")");
            }
            System.out.println();
        }

        System.out.println("==========調(diào)用類的方法===========");
        //調(diào)用類的方法
        Class<?> clazz3 = Class.forName("com.critc.vo.User1");
        Method method3 = clazz3.getMethod("setId", int.class);
        //method3.invoke(clazz.newInstance());//先調(diào)用new方法
        method3.invoke(clazz3.newInstance(), 20);//調(diào)用set方法

        User1 user1 = new User1("測(cè)試", 10, "123");
        Class clazz4 = user1.getClass();
        Method method4 = clazz4.getDeclaredMethod("getName");
        String name = (String) method4.invoke(user1);//調(diào)用get方法
        System.out.println(name);
    }
}

應(yīng)用場(chǎng)景主要包括以下:

1、參數(shù)替換,比如一段文字里面的參數(shù)${id},${name}等,傳過來一個(gè)對(duì)象,就可以先用正則表達(dá)式獲取這些參數(shù),然后調(diào)用參數(shù)的get方法
2、動(dòng)態(tài)調(diào)用一些列的方法,比如兩個(gè)類都繼承一個(gè)接口,要根據(jù)參數(shù)來判斷調(diào)用哪個(gè)類的哪個(gè)方法,就可以動(dòng)態(tài)調(diào)用了。
3、spring里面的BeanFactory,最常用的,后面會(huì)單獨(dú)講

源碼下載

本例子詳細(xì)源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容