反射

轉(zhuǎn)自:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

  • JAVA反射機(jī)制是在運(yùn)行狀態(tài)中钢悲,對于任意一個類屹耐,都能夠知道這個類的所有屬性和方法泛粹;對于任意一個對象胜臊,都能夠調(diào)用它的任意一個方法和屬性匣掸;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為 java 語言的反射機(jī)制霞揉。
  • Java 上指的是可以于運(yùn)行時加載竹海、探知、使用編譯期間完全未知的 classes彼绷。換句話說巍佑,Java 程序可以加載一個運(yùn)行時才得知名稱的 class,獲悉其完整構(gòu)造(但不包括 methods 定義)寄悯,并生成其對象實(shí)體萤衰、或?qū)ζ?fields 設(shè)值、或喚起其 methods猜旬。

1. 通過一個對象獲得完整的包名和類名

package Reflect; 

class Demo{ 
    //other codes...
} 

class hello{ 
    public static void main(String[] args) {
        Demo demo=new Demo();     
        System.out.println(demo.getClass().getName()); 
    }
}

【運(yùn)行結(jié)果】:
Reflect.Demo

2. 實(shí)例化 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.Person");
        }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

3. 通過 Class 實(shí)例化其他類的對象(調(diào)用無參構(gòu)造函數(shù))

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person{
    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;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    private String name;
    private int age;
}

class hello{ 
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        Person per=null;
        try {
            per=(Person)demo.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        per.setName("Rollen");
        per.setAge(20);
        System.out.println(per);
    }
}

【運(yùn)行結(jié)果】:
[Rollen 20]

  • 但是要注意脆栋,當(dāng)把 Person 中的默認(rèn)的無參構(gòu)造函數(shù)取消的時候,比如自己只定義一個有參數(shù)的構(gòu)造函數(shù)之后洒擦,會出現(xiàn)錯誤椿争。
    所以在編寫使用 Class 實(shí)例化其他類的對象的時候,一定要記得定義無參的構(gòu)造函數(shù)熟嫩。

4. 通過 Class 調(diào)用其他類中的構(gòu)造函數(shù)

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person {

    private String name;
    private int age;

    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;
    }

    @Override
    public String toString() {
        return "[" + this.name + "  " + this.age + "]";
    }

    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;
    }
}

class hello{ 
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        Person per1=null;
        Person per2=null;
        Person per3=null;
        Person per4=null;
        //取得全部的構(gòu)造函數(shù)
        Constructor<?> cons[]=demo.getConstructors();
        try{
            per1=(Person)cons[0].newInstance();
            per2=(Person)cons[1].newInstance("Rollen");
            per3=(Person)cons[2].newInstance(20);
            per4=(Person)cons[3].newInstance("Rollen",20);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(per1);
        System.out.println(per2);
        System.out.println(per3);
        System.out.println(per4);
    }
}

【運(yùn)行結(jié)果】:
[null 0]
[Rollen 0]
[null 20]
[Rollen 20]

5. 返回一個類實(shí)現(xiàn)的接口

package Reflect; 

class Demo{ 
    //other codes...
} 

interface China{
    public static final String name="Rollen";
    public static  int age=20;
    public void sayChina();
    public void sayHello(String name, int age);
}

class Person implements China{
    public Person() {

    }
    public Person(String sex){
        this.sex=sex;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public void sayChina(){
        System.out.println("hello ,china");
    }
    @Override
    public void sayHello(String name, int age){
        System.out.println(name+"  "+age);
    }
    private String sex;
}

class hello{
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        //保存所有的接口
        Class<?> intes[]=demo.getInterfaces();
        for (int i = 0; i < intes.length; i++) {
            System.out.println("實(shí)現(xiàn)的接口   "+intes[i].getName());
        }
    }
}

【運(yùn)行結(jié)果】:
實(shí)現(xiàn)的接口 Reflect.China

6. 取得其他類中的父類

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person implements China{
    ......
}

class hello{
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        //取得父類
        Class<?> temp=demo.getSuperclass();
        System.out.println("繼承的父類為:   "+temp.getName());
    }
}

【運(yùn)行結(jié)果】:
繼承的父類為: java.lang.Object

7. 獲得其他類中的全部構(gòu)造函數(shù)

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person implements China{
    ......
}

class hello{
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        Constructor<?>cons[]=demo.getConstructors();
        for (int i = 0; i < cons.length; i++) {
            System.out.println("構(gòu)造方法:  "+cons[i]);
        }
    }
}

【運(yùn)行結(jié)果】:
構(gòu)造方法: public Reflect.Person()
構(gòu)造方法: public Reflect.Person(java.lang.String)

8. 取得其他類的全部屬性

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person implements China{
    ......
}

class hello {
    public static void main(String[] args) {
        Class<?> demo = null;
        try {
            demo = Class.forName("Reflect.Person");
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("===============本類屬性========================");
        // 取得本類的全部屬性
        Field[] field = demo.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() + ";");
        }
        System.out.println("===============實(shí)現(xiàn)的接口或者父類的屬性========================");
        // 取得實(shí)現(xiàn)的接口或者父類的屬性
        Field[] filed1 = demo.getFields();
        for (int j = 0; j < filed1.length; j++) {
            // 權(quán)限修飾符
            int mo = filed1[j].getModifiers();
            String priv = Modifier.toString(mo);
            // 屬性類型
            Class<?> type = filed1[j].getType();
            System.out.println(priv + " " + type.getName() + " "
                    + filed1[j].getName() + ";");
        }
    }
}

【運(yùn)行結(jié)果】:
===============本類屬性========================
private java.lang.String sex;
===============實(shí)現(xiàn)的接口或者父類的屬性========================
public static final java.lang.String name;
public static final int age;

9. 通過反射調(diào)用其他類中的方法

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person implements China{
    ......
}

class hello {
    public static void main(String[] args) {
        Class<?> demo = null;
        try {
            demo = Class.forName("Reflect.Person");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try{
            //調(diào)用Person類中的sayChina方法
            Method method=demo.getMethod("sayChina");
            method.invoke(demo.newInstance());
            //調(diào)用Person的sayHello方法
            method=demo.getMethod("sayHello", String.class,int.class);
            method.invoke(demo.newInstance(),"Rollen",20);

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

【運(yùn)行結(jié)果】:
hello ,china
Rollen 20

10. 調(diào)用其他類的 set 和 get 方法

package Reflect; 

class Demo{ 
    //other codes...
} 

class Person implements China{
    ......
}

class hello {
    public static void main(String[] args) {
        Class<?> demo = null;
        Object obj=null;
        try {
            demo = Class.forName("Reflect.Person");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try{
            obj=demo.newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        setter(obj,"Sex","男",String.class);
        getter(obj,"Sex");
    }

    /**
     * @param obj
     *            操作的對象
     * @param att
     *            操作的屬性
     * */
    public static void getter(Object obj, String att) {
        try {
            Method method = obj.getClass().getMethod("get" + att);
            System.out.println(method.invoke(obj));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param obj
     *            操作的對象
     * @param att
     *            操作的屬性
     * @param value
     *            設(shè)置的值
     * @param type
     *            參數(shù)的屬性
     * */
    public static void setter(Object obj, String att, Object value,
                              Class<?> type) {
        try {
            Method method = obj.getClass().getMethod("set" + att, type);
            method.invoke(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

——更多——

參考:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秦踪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌椅邓,老刑警劉巖柠逞,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異景馁,居然都是意外死亡板壮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門裁僧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來个束,“玉大人,你說我怎么就攤上這事聊疲〔绲祝” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵获洲,是天一觀的道長阱表。 經(jīng)常有香客問我,道長贡珊,這世上最難降的妖魔是什么最爬? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮门岔,結(jié)果婚禮上爱致,老公的妹妹穿的比我還像新娘。我一直安慰自己寒随,他們只是感情好糠悯,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妻往,像睡著了一般互艾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讯泣,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天纫普,我揣著相機(jī)與錄音,去河邊找鬼好渠。 笑死昨稼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拳锚。 我是一名探鬼主播悦昵,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼晌畅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寡痰,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤抗楔,失蹤者是張志新(化名)和其女友劉穎棋凳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體连躏,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剩岳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了入热。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拍棕。...
    茶點(diǎn)故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖勺良,靈堂內(nèi)的尸體忽然破棺而出绰播,到底是詐尸還是另有隱情,我是刑警寧澤尚困,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布蠢箩,位于F島的核電站,受9級特大地震影響事甜,放射性物質(zhì)發(fā)生泄漏谬泌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一逻谦、第九天 我趴在偏房一處隱蔽的房頂上張望掌实。 院中可真熱鬧,春花似錦邦马、人聲如沸贱鼻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忱嘹。三九已至,卻和暖如春耕渴,著一層夾襖步出監(jiān)牢的瞬間拘悦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工橱脸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留础米,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓添诉,卻偏偏與公主長得像屁桑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子栏赴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評論 2 361

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