Java反射

定義:
Java反射機(jī)制是指在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象程拭,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制帆阳。
用一句話總結(jié)就是反射可以實(shí)現(xiàn)在運(yùn)行時(shí)可以知道任意一個(gè)類的屬性和方法哺壶。

Class類和類類型:
通過已有的類得到它的Class對象,共有三種方式:

package Reflect;
class Demo{
    //other codes...
}
 
class hello{
    public static void main(String[] args) {
        Class<?> demo1=null;
        Class<?> demo2=null;
        Class<?> demo3=null;
        try{
            //一般盡量采用這種形式
            demo1=Class.forName("Reflect.Demo");
        }catch(Exception e){
            e.printStackTrace();
        }
        demo2=new Demo().getClass();
        demo3=Demo.class;
         
        System.out.println("類名稱   "+demo1.getName());
        System.out.println("類名稱   "+demo2.getName());
        System.out.println("類名稱   "+demo3.getName());
         
    }
}

運(yùn)行結(jié)果:

類名稱   Reflect.Demo
類名稱   Reflect.Demo
類名稱   Reflect.Demo

獲取構(gòu)造函數(shù)Constructor:
Person類蜒谤,定義了幾個(gè)構(gòu)造方法:

package Reflect;
import java.lang.reflect.Constructor;
class Person{
     
    public Person() {
         
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    private String name;
    private int age;
}

通過無參構(gòu)造實(shí)例化對象:
在加上有參構(gòu)造函數(shù)后山宾,默認(rèn)無參構(gòu)造函數(shù)失效,一定要添上無參構(gòu)造函數(shù)鳍徽。

demo=Class.forName("Reflect.Person");
per=(Person)demo.newInstance();
per.setName("Rollen");
per.setAge(20);

通過反射:

demo=Class.forName("Reflect.Person");

Person per1=null;
Person per2=null;
Person per3=null;
Person per4=null;
//取得全部的構(gòu)造函數(shù)
Constructor<?> cons[]=demo.getConstructors();

per1=(Person)cons[0].newInstance();
per2=(Person)cons[1].newInstance("Rollen");
per3=(Person)cons[2].newInstance(20);
per4=(Person)cons[3].newInstance("Rollen",20);

System.out.println(per1);
System.out.println(per2);
System.out.println(per3);
System.out.println(per4);

獲取成員方法Method:

  • public Methods = getDeclaredMethods(); // 得到該類所有的方法资锰,不包括父類的。
  • public Methods = getMethods();// 得到該類所有的public方法阶祭,包括父類的绷杜。
public class Person {
    private String name;
    private int age;
    private String msg="hello wrold";
    public String getName() {
       return name;
    }

    public void setName(String name) {
       this.name = name;
    }

    public int getAge() {
       return age;
    }

    public void setAge(int age) {
       this.age = age;
    }

    public Person() {
    }

    private Person(String name) {
       this.name = name;
    System.out.println(name);
    }

    public void fun() {
       System.out.println("fun");
    }

    public void fun(String name,int age) {
       System.out.println("我叫"+name+",今年"+age+"歲");
    }
}

public class ReflectDemo {
    public static void main(String[] args){
       try {
           Class c = Class.forName("Reflect.Person");
           Object o = c.newInstance();
           Method method = c.getMethod("fun", String.class, int.class);
           method.invoke(o, "aaa", 10);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}

執(zhí)行結(jié)果:

我叫aaa,今年10歲
  • Method[] methods = c.getDeclaredMethods(); // 得到該類所有的方法,不包括父類的濒募。
  • Method[] methods = c.getMethods();// 得到該類所有的public方法鞭盟,包括父類的。
public class ReflectDemo {
    public static void main(String[] args){
       try {
           Class c = Class.forName("com.tengj.reflect.Person");
           Method[] methods = c.getDeclaredMethods();
           for(Method m:methods){
               String  methodName= m.getName();
               System.out.println(methodName);
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
}

獲取成員變量Field:

  • public Field getDeclaredField(String name) // 獲得該類自身聲明的所有變量瑰剃,不包括其父類的變量齿诉。
  • public Field getField(String name) // 獲得該類自所有的public成員變量,包括其父類變量晌姚。
public class ReflectDemo {
    public static void main(String[] args){
        try {
            Class c = Class.forName("Reflect.Person");
            //獲取成員變量
            Field field = c.getDeclaredField("msg"); //因?yàn)閙sg變量是private的粤剧,所以不能用getField方法
            Object o = c.newInstance();
            field.setAccessible(true);//設(shè)置是否允許訪問,因?yàn)樵撟兞渴莗rivate的挥唠,所以要手動(dòng)設(shè)置允許訪問抵恋,如果msg是public的就不需要這行了。
            Object msg = field.get(o);
            System.out.println(msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • Field[] fields = c.getDeclaredFields(); // 獲得該類自身聲明的所有變量宝磨,不包括其父類的變量弧关。
  • Field[] fields = c.getFields(); // 獲得該類自所有的public成員變量盅安,包括其父類變量。
public class ReflectDemo {
    public static void main(String[] args){
        try {
            Class c = Class.forName("com.tengj.reflect.Person");
            Field[] fields = c.getDeclaredFields();
            for(Field field :fields){
                System.out.println(field.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

還可以通過
Class<?> intes[]=Class.forName("Reflect.Person").getInterfaces();返回繼承的接口梯醒。
通過Class<?> temp=Class.forName("Reflect.Person").getSuperclass();返回繼承的父類宽堆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腌紧,一起剝皮案震驚了整個(gè)濱河市茸习,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壁肋,老刑警劉巖号胚,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浸遗,居然都是意外死亡猫胁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門跛锌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弃秆,“玉大人,你說我怎么就攤上這事髓帽〔ぷ” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵郑藏,是天一觀的道長衡查。 經(jīng)常有香客問我,道長必盖,這世上最難降的妖魔是什么拌牲? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮歌粥,結(jié)果婚禮上塌忽,老公的妹妹穿的比我還像新娘。我一直安慰自己失驶,他們只是感情好土居,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著突勇,像睡著了一般装盯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甲馋,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天埂奈,我揣著相機(jī)與錄音,去河邊找鬼定躏。 笑死账磺,一個(gè)胖子當(dāng)著我的面吹牛芹敌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垮抗,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氏捞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冒版?” 一聲冷哼從身側(cè)響起液茎,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辞嗡,沒想到半個(gè)月后捆等,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡续室,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年栋烤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挺狰。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡明郭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丰泊,到底是詐尸還是另有隱情薯定,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布趁耗,位于F島的核電站沉唠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏苛败。R本人自食惡果不足惜满葛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罢屈。 院中可真熱鬧嘀韧,春花似錦、人聲如沸缠捌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曼月。三九已至谊却,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哑芹,已是汗流浹背炎辨。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聪姿,地道東北人碴萧。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓乙嘀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親破喻。 傳聞我的和親對象是個(gè)殘疾皇子虎谢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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