Java反射總結(jié)

1、Class對象的獲取

Java中對象可以分為兩種,一種是實例對象无蜂,一種是Class對象。Class對象是在類加載的時候生成的蒙谓,而實例對象又是基于Class對象來生成的斥季。
Java中的反射使其擁有了動態(tài)語言的屬性。在程序開發(fā)的過程中累驮,反射技術(shù)應(yīng)用的核心就是Class對象的獲取酣倾。Class對象的獲取有如下三種方法,各有各的使用場景慰照。

public class TestReflect {

    public static void main(String[] args){

        Class<?> clazz1 = null; //Class clazz1 = null;
        Class<?> clazz2 = null; //Class clazz2 = null;
        Class<?> clazz3 = null; //Class clazz3 = null;           
        //使用<?>或者不使用<?>兩者是沒有區(qū)別的,只不過Class支持泛型以后加上<?>會更加規(guī)范
        //1琉朽、使用Class的靜態(tài)方法毒租,該方法會產(chǎn)生異常,需要進行異常處理箱叁,因為可能沒有與所傳入字符串相對應(yīng)的類
        try{

            Class clazz1 = Class.forName("InnerTest");
        } catch (ClassNotFoundException e) {

            e.printStackTrace();
        }

        //2墅垮、使用Java中類字面量class獲得Class對象
        Class clazz2 = InnerTest.class;

        //3、使用繼承于Object的getClass()方法耕漱,該方法是native方法
        InnerTest innerTest = new InnerTest();
        Class clazz3 = innerTest.getClass();
    }
}

class InnerTest {

}

2算色、構(gòu)造實例對象

獲得Class對象之后,采用newInstance()螟够,該方法的返回類型是T灾梦,是一個泛型類型。如果Class對象的類型為Class或者Class<?>妓笙,則需要強制類型轉(zhuǎn)換若河。有兩種構(gòu)造實例對象的方法:1、獲得Class對象以后調(diào)用newInstance()方法寞宫;2萧福、獲得Constructor對象以后調(diào)用newInstance()方法。實際上前者也會調(diào)用后者的方法辈赋。

import java.lang.reflect.Constructor;
public class TestReflect {

    public static void main(String[] args){

        //若沒有傳入類型參數(shù)鲫忍,使用newInstance()方法生成對象的時候膏燕,會有兩種情況:1、只能生成Object對象悟民;2坝辫、進行強制類型轉(zhuǎn)換;
        Class<?> clazz1 = null;
        //此處傳入了類型參數(shù)逾雄,使用newInstance()方法生成對象的時候阀溶,無需進行強制類型轉(zhuǎn)換;
        Class<InnerTest> clazz2 = null;
        clazz1 = InnerTest.class;
        clazz2 = InnerTest.class;

        //1鸦泳、使用newInstance()的方法返回實例對象
        try{
            Object test11 = clazz1.newInstance();//只能生成Object對象
            InnerTest test12 = (InnerTest) clazz1.newInstance();//必須進行強制類型轉(zhuǎn)換
            InnerTest test2 = clazz2.newInstance();//直接可以生成所需的類型對象
        }catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InstantiationException e){
            e.printStackTrace();
        }

        //2银锻、直接獲取構(gòu)造函數(shù)
        Constructor<?> c1 = null;
        Constructor<InnerTest> c2 = null;
        try{
            c1 =clazz1.getDeclaredConstructor();
            c2 = clazz2.getDeclaredConstructor();
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try{
            Object innerTest11 = c1.newInstance(null);
            InnerTest innerTest112 = (InnerTest)c1.newInstance(null);
            InnerTest innerTest2 = c2.newInstance(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class InnerTest {

}

3、構(gòu)造方法

在獲得Class的對象以后做鹰,通過該對象獲得對應(yīng)的構(gòu)造函數(shù)击纬,如果同時存在多個構(gòu)造函數(shù)。

import java.lang.reflect.Constructor;

public class TestReflect {

    public static void main(String[] args){

        Class<InnerTest> clazz = null;
        clazz = InnerTest.class;
        Constructor<InnerTest> c1 = null;
        Constructor<InnerTest> c2 = null;
        Constructor<InnerTest> c3 = null;
        try{

            c1 = clazz.getDeclaredConstructor();
            c2 = clazz.getDeclaredConstructor(int.class);
            c3 = clazz.getDeclaredConstructor(int.class,int.class);
        }catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try{
            InnerTest innerTest1 = c1.newInstance();
            System.out.println("innerTest1 a: " + innerTest1.a + " b: " + innerTest1.b + " c: " + innerTest1.c);
            InnerTest innerTest2 = c2.newInstance(6);
            System.out.println("innerTest2 a: " + innerTest2.a + " b: " + innerTest1.b + " c: " + innerTest2.c);
            InnerTest innerTest3 = c3.newInstance(6,12);
            System.out.println("innerTest3 a: " + innerTest3.a + " b: " + innerTest1.b + " c: " + innerTest3.c);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class InnerTest {
    static int a = 2;

    int b;

    int c;

    public InnerTest() {

    }

    public InnerTest(int b) {
        this.b = b;
    }

    public InnerTest(int b, int c) {
        this.b = b;
        this.c = c;
    }
}

4钾麸、非構(gòu)造方法

非構(gòu)造方法的獲取和使用與構(gòu)造方法有著明顯的區(qū)別:1更振、獲取非構(gòu)造方法不僅需要指定參數(shù)的類型,還需要指定方法名饭尝;2肯腕、非構(gòu)造方法的調(diào)用分為兩種情況:a),靜態(tài)方法調(diào)用钥平;b)实撒,非靜態(tài)方法調(diào)用

import java.lang.reflect.Method;

public class TestReflect {

    public static void main(String[] args){

        Class<InnerTest> clazz = null;
        clazz = InnerTest.class;
        try{
            //需要指定方法名和參數(shù)類型
            Method m1 = clazz.getDeclaredMethod("getA");
            Method m2 = clazz.getDeclaredMethod("setA", int.class);
            //調(diào)用靜態(tài)方法時候,invoke函數(shù)的第一個參數(shù)為null涉瘾;
            System.out.println(m1.invoke(null));
            m2.invoke(null,4);
            System.out.println(m1.invoke(null));

            InnerTest innerTest = new InnerTest();
            Method m3 = clazz.getDeclaredMethod("getB");
            Method m4 = clazz.getDeclaredMethod("setB", int.class);
            //調(diào)用非靜態(tài)方法的時候知态,需要指定對象名;
            System.out.println(m3.invoke(innerTest));
            m4.invoke(innerTest,8);
            System.out.println(m3.invoke(innerTest));
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class InnerTest {
    static int a = 2;

    int b;

    public static int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    public static void setA(int a) {
        InnerTest.a = a;
    }

    public void setB(int b) {
        this.b = b;
    }
}

5立叛、域

域的獲取相對簡單负敏,只需要傳入變量名字∶厣撸可以獲取域的值和設(shè)置域的值其做。更厲害的時候可以通過setAccessible(),進而訪問private的變量

import java.lang.reflect.Field;

public class TestReflect {

    public static void main(String[] args){

        Class<InnerTest> clazz = null;
        clazz = InnerTest.class;
        try{
            Field a = clazz.getDeclaredField("a");
            System.out.println("a: " + a.getInt(null));
            a.setInt(null,4);
            System.out.println("a: " + a.getInt(null));

            InnerTest innerTest = new InnerTest();
            Field b = clazz.getDeclaredField("b");
            System.out.println("b: " + b.getInt(innerTest));
            b.setInt(innerTest,20);
            System.out.println("b: " + b.getInt(innerTest));

            Field c = clazz.getDeclaredField("c");
            System.out.println("accessible: " + c.isAccessible());
            c.setAccessible(true);
            System.out.println("accessible: " + c.isAccessible()+ " c: " +c.getInt(innerTest));
            c.setInt(innerTest,40);
            System.out.println("accessible: " + c.isAccessible()+ " c: " +c.getInt(innerTest));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class InnerTest {
    static int a = 2;

    int b = 10;

    private int c = 20;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赁还,一起剝皮案震驚了整個濱河市庶柿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秽浇,老刑警劉巖浮庐,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡审残,警方通過查閱死者的電腦和手機梭域,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來搅轿,“玉大人病涨,你說我怎么就攤上這事¤捣兀” “怎么了既穆?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵管挟,是天一觀的道長刹枉。 經(jīng)常有香客問我,道長效五,這世上最難降的妖魔是什么黎茎? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任囊颅,我火速辦了婚禮,結(jié)果婚禮上傅瞻,老公的妹妹穿的比我還像新娘踢代。我一直安慰自己,他們只是感情好嗅骄,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布胳挎。 她就那樣靜靜地躺著,像睡著了一般溺森。 火紅的嫁衣襯著肌膚如雪慕爬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天儿惫,我揣著相機與錄音澡罚,去河邊找鬼伸但。 笑死肾请,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的更胖。 我是一名探鬼主播铛铁,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼却妨!你這毒婦竟也來了饵逐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤彪标,失蹤者是張志新(化名)和其女友劉穎倍权,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捞烟,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡薄声,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年当船,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片默辨。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡德频,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缩幸,到底是詐尸還是另有隱情壹置,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布表谊,位于F島的核電站钞护,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏铃肯。R本人自食惡果不足惜患亿,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望押逼。 院中可真熱鬧步藕,春花似錦、人聲如沸挑格。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漂彤。三九已至雾消,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挫望,已是汗流浹背立润。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媳板,地道東北人桑腮。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像蛉幸,于是被迫代替她去往敵國和親破讨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法奕纫,類相關(guān)的語法提陶,內(nèi)部類的語法,繼承相關(guān)的語法匹层,異常的語法隙笆,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 概念介紹 Java反射機制JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法撑柔;對于任...
    niaoge2016閱讀 524評論 0 2
  • 一:java概述:1煤率,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境乏冀,java的開發(fā)工...
    ZaneInTheSun閱讀 2,651評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蝶糯,服務(wù)發(fā)現(xiàn),斷路器辆沦,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 過去的幾年昼捍,我只能懶懶散散地做到一年看兩本書,有時間就看肢扯,沒時間就對自己說工作太忙了妒茬,等有空了再看(可是當(dāng)初并不及...
    天蝎麥子閱讀 201評論 2 4