java 反射技術(shù)

1.

反射技術(shù):動態(tài)的獲取類以及類中的成員贴彼,并可以調(diào)用該成員
* 以前是有什么類爆阶,就new什么對象;沒有類缭黔,給什么類就new什么對象
*
* 無論new什么對象,都需要先獲取字節(jié)碼文件蒂破。
* 如何獲取呢馏谨?發(fā)現(xiàn)java已經(jīng)對字節(jié)碼文件進行了描述用的Class類完成的。


image.png

2.*

反射技術(shù):動態(tài)的獲取類以及類中的成員附迷,并可以調(diào)用該成員
* 以前是有什么類惧互,就new什么對象;沒有類喇伯,給什么類就new什么對象
*
* 無論new什么對象喊儡,都需要先獲取字節(jié)碼文件。
* 如何獲取呢稻据?發(fā)現(xiàn)java已經(jīng)對字節(jié)碼文件進行了描述用的Class類完成的艾猜。
*
* 如何獲取一個字節(jié)碼文件的對象呢?
* 方式一:Object getClass();
* 如 new Person().getClass().
* 弊端:方法一演示完發(fā)現(xiàn)在反射技術(shù)里該方法不合適,應(yīng)為反射技術(shù)不明確具體類的匆赃。
*
* 方式二:所有的數(shù)據(jù)類型都有自己的Class對象淤毛,表示方法很簡單。
* 每一個數(shù)據(jù)類型都有一個默認的靜態(tài)屬性—— .class算柳,用該屬性就可以獲取到字節(jié)碼文件對象
* Class clazz=Person.class;
* int.class;
* 每一種類型都具備
* 弊端:雖然不用對象調(diào)用了低淡,但還是要用具體的得調(diào)用靜態(tài)屬性
*
重點
方式三:反射技術(shù)中最常用的方法:在Class類中找到了forName方法,通過名稱就可以獲取對性的字節(jié)碼文件對象瞬项。
* public static void methodDemo_3( ) throws ClassNotFoundException{
* String className = "cn.itcast.domain.person";//一定要把包名+類名寫全2榕啤!滥壕!
* Class clazz=Class.forName(className);
* System.out.println(clazz);

3.

newInstance( ) : 創(chuàng)建此Class對象所表示的類的一個實例纸颜。 如同使用一個帶有空參數(shù)列表的new表達式實例化對象,如果該類尚未初始化绎橘,則初始化這個類胁孙。
實例:


public class Person {
private int age;
private String name;
public Person() {
    super();
    
}
public Person(int age, String name) {
    super();
    this.age = age;
    this.name = name;
}


}
package cn.itcast.reflect;

public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    /*
     * 演示如何根據(jù)給定名稱獲取到指定Class對象后建立該類的對象呢?
     */
    getObject();
}

//空參數(shù)構(gòu)造函數(shù)
private static void getObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    //1.根據(jù)給定的類名獲取Class對象
    String name="cn.itcast.domain.Person";
    Class clazz=Class.forName(name);//通過名稱就可以獲取對性的字節(jié)碼文件對象
    Object obj=clazz.newInstance();//創(chuàng)建一個Person類對象称鳞,默認調(diào)用該類的空參數(shù)構(gòu)造函數(shù)
    // java.lang.InstantiationException:沒有調(diào)用到與之對應(yīng)的構(gòu)造函數(shù)
    //記住涮较,一般被反射得的類都帶有空參數(shù)構(gòu)造函數(shù)。
    
    //Person p=new Person()冈止;
}
}

new對象的另外一種方式狂票,通過指定構(gòu)造器完成:

private static void getObject2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    String name="cn.itcast.domain.Person";
    Class clazz=Class.forName(name);//通過名稱就可以獲取對性的字節(jié)碼文件對象
    /*
     * 萬一給定類中沒有空參數(shù)呢?
     * 可以先獲取指定的構(gòu)造函數(shù)熙暴,再通過該構(gòu)造函數(shù)進行實例化闺属。
     */
    //1.通過Class獲取指定構(gòu)造函數(shù),比如兩個參數(shù)
    Constructor cons=clazz.getConstructor(String.class,int.class);//類型對象
    Object obj=cons.newInstance("aaa",23);
}

5.字節(jié)碼文件對象的其他方法:

:getxxx():獲取公有的
getDeclaredXXX():可以獲取私有的

String className="cn.itcast.domain.Person";
Class clazz=Class.forName(className);
//獲取指定age字段
//Field field =clazz.getField("age");//該方法只能獲取公有的
Field field=clazz.getDeclaredField("age");//該方法可以獲取私有的
System.out.println(field);

暴力訪問字節(jié)碼對象值

//要對非靜態(tài)的字段必須有對象
Object obj=clazz.newInstance();
//需要使用父類的方法將權(quán)限檢查能力取消周霉。
field.setAccessible(true);//如果沒有這一步會報錯掂器,因為age是私有的,不能直接獲取
field.set(obj, 40);
System.out.println(field.get(obj) );

代碼如下:

package cn.itcast.reflect.field;

import java.lang.reflect.Field;

public class ReflectFieldDemo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
          getFieldDemo();
    }

    private static void getFieldDemo() throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
        String className="cn.itcast.domain.Person";
        Class clazz=Class.forName(className);
        //獲取指定age字段
        //Field field =clazz.getField("age");//該方法只能獲取公有的
        Field field=clazz.getDeclaredField("age");//該方法可以獲取私有的
        System.out.println(field);  
        
        //要對非靜態(tài)的字段必須有對象
        Object obj=clazz.newInstance();
        //需要使用父類的方法將權(quán)限檢查能力取消俱箱。
        field.setAccessible(true);//如果沒有這一步會報錯国瓮,因為age是私有的,不能直接獲取
        field.set(obj, 40);
        System.out.println(field.get(obj) );
                
    }

}

6.動態(tài)地獲取方法 類中的字段構(gòu)造函數(shù)方法
person類:

package cn.itcast.domain;

public class Person {
private int age;
private String name;
public Person() {
    super();
    
}
public Person(int age, String name) {
    super();
    this.age = age;
    this.name = name;
}
public void show(){
    System.out.println("Person show run");
}

public static void staticShow(){
    System.out.println("Person static show run");
}

public void paramShow(String name,int age){
    System.out.println("show"+name+"----"+age);
}


}
package cn.itcast.reflect.method;

import java.lang.reflect.Method;

public class ReflectMethodDemo {

    public static void main(String[] args) throws Exception {
        getMethodDemo();
        getMethodDemo2();
        getMethodDemo3();
    }

    //反射方法狞谱,非靜態(tài)乃摹,無參數(shù)的show方法。
    private static void getMethodDemo() throws Exception {
        String className="cn.itcast.domain.Person";
        Class clazz=Class.forName(className);
        //反射方法跟衅,非靜態(tài)孵睬,無參數(shù)的show方法。
        Method method=clazz.getMethod("show", null);
        
        Object obj=clazz.newInstance();
        
        //方法的調(diào)用運行
        method.invoke(obj, null);
        
    }

    //反射方法与斤,靜態(tài)肪康,無參數(shù)的show方法。
    private static void getMethodDemo2() throws Exception {
        String className="cn.itcast.domain.Person";
        Class clazz=Class.forName(className);
        //反射方法撩穿,靜態(tài)磷支,無參數(shù)的show方法。
        Method method=clazz.getMethod("staticShow", null);
        //這里不需要創(chuàng)建實例對象 因為靜態(tài)
        //方法的調(diào)用運行
        method.invoke(null,null);
    }
    
    //反射方法食寡,非靜態(tài)雾狈,帶參數(shù)的show方法。
    private static void getMethodDemo3() throws Exception {
        String className="cn.itcast.domain.Person";
        Class clazz=Class.forName(className);
        
        //反射方法抵皱,靜態(tài)善榛,帶參數(shù)的show方法。
        Method method=clazz.getMethod("paramShow",String.class,int.class);
        
        Object obj=clazz.newInstance();
        method.invoke(obj, "hhaha",20);
        
    }
}

結(jié)果:


image.png

7.反射技術(shù)--應(yīng)用場景

希望后期出現(xiàn)了設(shè)備后呻畸,可以不修改NoteBookMain的代碼移盆,還可以不斷加入新設(shè)備,就是反射技術(shù)

筆記本類 class NoteBook:

package 反射技術(shù);

public class NoteBook {
public void run(){
    System.out.println("notebook run");
}
/*
 * 使用USB設(shè)備
 */
public void useUSB(USB usb){
    if(usb!=null){
        usb.open();
        usb.close();
    }
}
}

USB接口:

package 反射技術(shù);

public interface USB {
void open();
void close();
}

實現(xiàn)USB接口的鼠標類:

package 反射技術(shù);

public class MouseByUSB implements USB {

    public void open() {
     System.out.println("mouse close");
    }

    @Override
    public void close() {
        System.out.println("mouse open");
    }

    
}

配置文件:

image.png

NoteBookMain筆記本實類:

package 反射技術(shù);

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class NoteBookMain {

    public static void main(String[] args) throws IOException, Exception {
        NoteBook book=new NoteBook();
        book.run();
         book.useUSB(null);
         //因為有了鼠標,所以在需要的源程序中伤为,創(chuàng)建鼠標對象并傳到筆記本
         //希望后期出現(xiàn)了設(shè)備后咒循,可以不修改NoteBookMain的代碼,還可以不斷加入新設(shè)備,就是反射技術(shù)
         //book.useUSB(new MouseByUSB());通過反射來解決問題
         
         
         //對外提供配置文件
         File configFile=new File("usb.properties");
         if(!configFile.exists()){
             configFile.createNewFile();
         }
         
        //讀取流和配置文件關(guān)聯(lián)
         FileInputStream fis=new FileInputStream(configFile);
         
         Properties prop=new Properties();
         //將流中的數(shù)據(jù)加載到prop
         prop.load(fis);
         
         for(int x=1;x<=prop.size();x++){
             String classname=prop.getProperty("usb"+x);
             
             //根據(jù)設(shè)備名字找到設(shè)備的類
             Class clazz=Class.forName(classname);
             //把類new成對象绞愚,把對象強轉(zhuǎn)換為USB類型
             USB usb=(USB)clazz.newInstance();
             book.useUSB(usb);
         }
         fis.close();
    }

}

反射技術(shù)完結(jié)叙甸,撒花!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末位衩,一起剝皮案震驚了整個濱河市裆蒸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糖驴,老刑警劉巖僚祷,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贮缕,居然都是意外死亡久妆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門跷睦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筷弦,“玉大人,你說我怎么就攤上這事抑诸±们伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵蜕乡,是天一觀的道長奸绷。 經(jīng)常有香客問我,道長层玲,這世上最難降的妖魔是什么号醉? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任反症,我火速辦了婚禮,結(jié)果婚禮上畔派,老公的妹妹穿的比我還像新娘铅碍。我一直安慰自己,他們只是感情好线椰,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布胞谈。 她就那樣靜靜地躺著,像睡著了一般憨愉。 火紅的嫁衣襯著肌膚如雪烦绳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天配紫,我揣著相機與錄音径密,去河邊找鬼。 笑死躺孝,一個胖子當(dāng)著我的面吹牛睹晒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播括细,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼伪很,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奋单?” 一聲冷哼從身側(cè)響起锉试,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎览濒,沒想到半個月后呆盖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡贷笛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年应又,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乏苦。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡株扛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汇荐,到底是詐尸還是另有隱情洞就,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布掀淘,位于F島的核電站旬蟋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏革娄。R本人自食惡果不足惜倾贰,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一冕碟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匆浙,春花似錦安寺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叹放。三九已至饰恕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間井仰,已是汗流浹背埋嵌。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俱恶,地道東北人雹嗦。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像合是,于是被迫代替她去往敵國和親了罪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355