Java基礎筆記-反射及應用

來源:互聯網
上載者:User

標籤:java   反射   

反射:
動態擷取位元組碼檔案對象(Person.class),並對其成員進行運行。
動態擷取位元組碼檔案對象的方式:
1:任何一個對象都是由位元組碼檔案對象建立的,所以任何一個對象都可以得到自己的位元組碼檔案對象
那麼這個功能應該定義在Object中,所以使用 getClass()
需要先new對象

  2:每種資料類型都有一個 靜態class 屬性,通過該屬性可以得到位元組碼檔案對象    不需要new對象,但是需要Person類存在  3:Class類提供了一個靜態forName(String str)方法     只需要提供字串形式的包名+類名
1.Person person1 = new Person();//先載入Person.class到方法區Class<? extends Person> claz1 = person1.getClass();//得到了Person.classPerson person2 = new Person();Class<? extends Person> claz2 = person2.getClass();//得到了 Person.classSystem.out.println(claz1==claz2);//true ---->位元組碼檔案只載入一次到方法區,所以兩次得到的是同一個2.Class<Person> claz1 = Person.class;3.Class<?> claz1 = Class.forName("com.reflect.Person");

動態擷取位元組碼檔案對象,並建立對象:
1)調用無參構造方法建立對象

//當無參的構造方法不存在時,會發生InstantiationException    //當構造方法的許可權過低時,會發生IllegalAccessException    public static void createObj1() throws ClassNotFoundException, InstantiationException, IllegalAccessException    {        //Person person = new Person();        //擷取位元組碼檔案對象---Person.class        Class<?> claz = Class.forName("com.reflect.Person");                    //使用Class提供的newInstance()方法建立Person類型的對象        Object obj = claz.newInstance();//使用無參的構造方法建立對象        Person person = (Person)obj;        System.out.println(person);}

2)使用有參數的構造方法建立對象

public static void createObj2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException    {   //Person person = new Person("小紅",20);        //擷取位元組碼檔案對象---Person.class        Class<?> claz = Class.forName("com.reflect.Person");                //得到構造方法所屬的Constructor類型的對象        Constructor<?> constructor = claz.getConstructor(String.class,int.class);               //使用構造方法建立對象--使用Constructor提供的建立對象的功能        Person person =(Person)constructor.newInstance("小紅",20);        System.out.println(person);}

3)動態建立對象並給屬性賦值

Class<?> claz = Class.forName("com.reflect.Person");         //得到屬性name所屬的 Field類型的對象//Field field = claz.getField("name");//只能擷取許可權是public 的屬性//System.out.println(field);//NoSuchFieldExceptionField field = claz.getDeclaredField("name");//因為name是非靜態屬性,所以必須通過對象訪問,所以先建立對象Object obj = claz.newInstance();//設定name屬性為可訪問的field.setAccessible(true);// 該方法是從父類中繼承的//使用Field類提供的賦值功能,給屬性賦值field.set(obj, "小紅");System.out.println(obj);

4)調用靜態方法

public static void method3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException    {        //擷取位元組碼檔案對象---Person.class         Class<?> claz = Class.forName("com.reflect.Person");         ///擷取被調用的方法所屬的 Method類型的對象         Method method = claz.getMethod("function", null);         //執行方法         method.invoke(null, null);}

5)通過對象調用無參方法

public static void method1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException    {        // Person person = new Person();person.show();        //擷取位元組碼檔案對象---Person.class         Class<?> claz = Class.forName("com.reflect.Person");         //擷取被調用的方法所屬的 Method類型的對象         Method method = claz.getMethod("show", null);         //show()屬於非靜態方式,需要對象去調用         Object obj = claz.newInstance();         //執行方法         method.invoke(obj, null);}

6)通過對象調用有參方法

//調用帶參的方法public static void method2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{        //擷取位元組碼檔案對象---Person.class         Class<?> claz = Class.forName("com.reflect.Person");               //擷取被調用的方法所屬的 Method類型的對象         Method method = claz.getMethod("fun", String.class);                 //fun()屬於非靜態方式,需要對象去調用         Object obj = claz.newInstance();         //執行方法         method.invoke(obj, "hello");}

反射應用:
這裡有一台筆記本,剛開始只有外設滑鼠。後來增加鍵盤、網路攝影機等等。
筆記本有running方法和use方法.外設都有open和close方法

public class NoteBook {     public void runing(){        System.out.println("電腦運行");    }       public void useKeyBoard(KeyBoard kb){        if(kb!=null){            kb.open();            kb.close();        }    }}調用:NoteBook noteBook = new NoteBook();noteBook.runing();KeyBoard keyBoard = new KeyBoard ();noteBook.use(keyBoard );

如果添加外設滑鼠呢?
NoteBook又得添加一個useMouse(Mouse mouse){..}方法,如果再添加外設的話,還得添加相應的方法。
當然,這裡很容易解決,定義一個借口Usb.

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

然後讓外設去實現這個介面,
在NoteBook裡面只用定義一個

useUsb(Usb usb){    usb.open();    usb.close();}在主程裡調用:Usb keyBoard = new KeyBoard ();noteBook.useUsb(keyBoard );Usb mouse = new Mouse();noteBook.useUsb(mouse);

如果還要添加外設,只用添加相應的類並實現Usb介面即可,那麼問題來了,主程式裡面又得new新的對象,調用相同的語句。

解決方案就可以用反射了:

1.把所有的外設添加到一個設定檔中
usb1=com.reflect.test.KeyBoard
usb2=com.reflect.test.Mouse
2.主程式裡調用

Properties properties = new Properties();FileInputStream fileInputStream = new FileInputStream("config\\config.properties");properties.load(fileInputStream);            for(int i=1;i<=properties.size();i++){       String value properties.getProperty("usb"+i);       Class<?> claz = Class.forName(value);       Object obj = claz.newInstance();       Usb usb = (Usb)obj;       noteBook.useUsb(usb);}

–>添加外設只用在設定檔中添加,主程式調用不用修改

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Java基礎筆記-反射及應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.