亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java反射機制的實現詳解

2019-11-26 16:07:55
字體:
來源:轉載
供稿:網友

很多主流框架都使用了反射技術.像ssh框架都采用兩種技術 xml做配置文件+反射技術.


與反射有關的類包.

java.lang.reflect.*;和java.lang.Class;


Java中所有類型(包括基本類型)都對應一個Class對象,這個Class就是java.lang.Class。即每一個類型,在Class中都有一個Class對象跟它對應.Class 沒有公共構造方法。注意不是沒有,是沒有公共的.


如何獲得Class對象

復制代碼 代碼如下:

.針對每一個對象.getCalss(),可以得到對應的Class.
.Class.forName(String),String的寫法:包名.類名.就會創建包名.類名對應的那個對象
注:1.2只適用于引用類型
.對于基本類型:封裝類.TYPE代表了對應的基本類型的Class對象.Integer.TYPE對應的是int的Class對象
注:3只適用于基本類型
.類型,Class。<第4種是通用的.>
上面的4種方法,只有方法2是動態的,只要換一個包就可以了.它具有動態潛質.所以真正意義的想體現動態編程只能使用方法2.

每種類型的Class對象只有一個,即他們的地址只有一個,但是不同類型是不同的.

所以下面的打印結果都為true.

復制代碼 代碼如下:

//對與引用類型
Class c1 = "".getClass();
Class c2 =     Class.forName("java.lang.String");
Class c3 = String.class;
System.out.println(c1 ==c2);//true
//對于基本類型
Class num1 = Integer.TYPE;
Class num2 = int.class;
System.out.println(num1 == num2);//true

反射獲取類中的成員的相關方法

[獲取構造<根據參數類型>](使用時一般用不帶declared)

復制代碼 代碼如下:

Constructor<T> getConstructor(Class<?>... parameterTypes)
      返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公共構造方法。
 Constructor<?>[] getConstructors()
      返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的所有公共構造方法。
 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
      返回一個 Constructor 對象,該對象反映此 Class 對象所表示的類或接口的指定構造方法。
 Constructor<?>[] getDeclaredConstructors()
      返回 Constructor 對象的一個數組,這些對象反映此 Class 對象表示的類聲明的所有構造方法。

[獲取屬性<根據屬性名>](使用時一般用是帶declared,因為屬性一般都是私有的)
復制代碼 代碼如下:

Field getField(String name)
      返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段。
 Field[] getFields()
      返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的所有可訪問公共字段。
 Field getDeclaredField(String name)
      返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。
 Field[] getDeclaredFields()
      返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的所有字段。

[獲取方法<方法名加上參數類型>](使用時一般用不帶declared的)
復制代碼 代碼如下:

Method getMethod(String name, Class<?>... parameterTypes)
      返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。
 Method[] getMethods()
      返回一個包含某些 Method 對象的數組,這些對象反映此 Class 對象所表示的類或接口(包括那些由該類或接口聲明的以及從超類和超接口繼承的那些的類或接口)的公共 member 方法。
 Method getDeclaredMethod(String name, Class<?>... parameterTypes)
      返回一個 Method 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明方法。
 Method[] getDeclaredMethods()
      返回 Method 對象的一個數組,這些對象反映此 Class 對象表示的類或接口聲明的所有方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。
 T newInstance()
      創建此 Class 對象所表示的類的一個新實例。 <new Instance()可以動態的創建對象>
 String toString()
      將對象轉換為字符串。

注意:

new Instance()調用的是無參構造,如果該類沒有無參構造方法,則newInstance()會產生異常.

有declared的方法是支持私有,但是不支持繼承,無declared的方法支持繼承,不支持私有,且只能取出public的東西.

因此取屬性的時候一般來說是帶declared的,因為屬性一般都是私有的,取方法時一般是不帶declared的,取構造時一般也是不帶declared的.

實例模擬反射獲取類中的相關屬性和方法

利用反射對屬性賦值

Field中的方法

 Object get(Object obj)

  返回指定對象上此 Field 表示的字段的值。

      Field f = c.getXXField(屬性名);

      值 = f.get(對象);

 void set(Object obj, Object value)

  將指定對象變量上此 Field 對象表示的字段設置為指定的新值。

  f.set(對象,值);

 Class<?> getType()

  返回一個 Class 對象,它標識了此 Field 對象所表示字段的聲明類型。

      用于獲取屬性的類型(返回Class對象).

復制代碼 代碼如下:

Class c = Student.class;
    Object obj  = c.newInstance();            //創建Student類的對象
    Field f = c.getDeclaredField("name");        //獲取name屬性
    f.setAccessible(true);                    //設置私有可以訪問.
    f.set(obj, "zhangsan");
    System.out.println(f.get(obj));             //獲取obj的name屬性的值.

利用反射調用構造

對于構造真正調用是在調用newInstance()方法時.

復制代碼 代碼如下:

Class c = Class.forName("com.clazz.reflect.Student");
    Constructor con = c.getConstructor();         //沒有執行構造,
    Object cObj = c.getConstructor().newInstance();//調用無參的構造方法
    Constructor conAll = c.getConstructor(int.class,String.class,int.class);
    Object caobj = conAll.newInstance(1001,"zjamgs",234235);//調用含參的構造方法.
    System.out.println(caobj);                  //打印輸出

利用反射調用方法

對象.方法名(值1,2,3);

Method m = c.getMethoed(方法名,參數類型...);

m.invoke(對象,方法調用的參數 )如果底層方法所需的形參數為 0,則所提供的 args 數組長度可以為 0 或 null。

復制代碼 代碼如下:

Class c = Class.forName("com.clazz.reflect.Student");
    Object obj = c.newInstance();    //創建Sutdent對象.
    Method msetName = c.getMethod("setName", String.class);//obj無須轉換類型
    msetName.invoke(obj, "zhangsan");//調用方法setName, 并傳參.
    Method msetId = c.getMethod("setId", int.class);
    msetId.invoke(obj, 409090202);
    System.out.println(obj);

反射應用實例

實體類

復制代碼 代碼如下:

package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
 *
 *  User.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發送郵件</a>
 *   
 *  @since     : 1.0        創建時間:    2013-2-26        下午01:43:56
 *    
 *  TODO     :    class User.java is used for ...
 *
 */
public class User implements Serializable{

    private String test;

    public void execute(String name,int age){
        System.out.println("name=" + name + ",age=" + age);
    }
}


反射測試類
復制代碼 代碼如下:

package org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
 *
 *  ReflectEx.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發送郵件</a>
 *   
 *  @since     : 1.0        創建時間:    2013-2-26        下午01:46:00
 *    
 *  TODO     :    class ReflectEx.java is used for ...
 *
 */
public class ReflectEx {

    public static void main(String[] args)throws Exception {
        Class cls = Class.forName("org.dennisit.reflect.entity.User");
        Object obj = cls.newInstance();       //創建User的對象
        Field f = cls.getDeclaredField("test");    //獲取test屬性
        f.setAccessible(true);                    //打開私有屬性test的訪問權限
        f.set(obj, "zhangsan");                    //為test重新復制
        System.out.println(f.get(obj));            //獲取obj的test屬性值
        //根據方法名execute獲取方法
        java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
        m.invoke(obj, "dennisit",23);            //調用execute方法
    }
}


運行效果
復制代碼 代碼如下:

zhangsan
name=dennisit,age=23

編寫一個反射動態實例化類的例子
復制代碼 代碼如下:

package org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
 *
 *  DynamicReflect.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發送郵件</a>
 *   
 *  @since     : 1.0        創建時間:    2013-2-26        下午01:58:12
 *    
 *  TODO     :    利用反射動態實例化的例子
 *
 */
public class DynamicReflect {

    public static Object getInstance(String className,Map<String,Object> map)throws Exception{
        Class c = Class.forName(className);
        Object obj = c.newInstance();                //對象對象
        Set<String> keys = map.keySet();            //獲取對應的所有屬性
        Field[] fAll = c.getDeclaredFields();        //獲取類中所有屬性
        for(int i=0;i<fAll.length;i++){
            for(String key:keys){                    //循環匹配
                if(fAll[i].getName().equals(key)){    //如果用戶傳入的屬性跟獲取到的類中的屬性名匹配
                    Field f = c.getDeclaredField(key);//獲取該屬性
                    //構建setXxx()方法名
                    String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
                    Method method = c.getMethod(methodName, f.getType());//根據構建的用戶名獲取對應的方法
                    method.invoke(obj, map.get(key));//方法調用
                }else{
                    continue;
                }
            }
        }
        return obj;
    }
}


接下來我們測試我們編寫的動態反射實例化例子

實體類

復制代碼 代碼如下:

package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
 *
 *  User.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發送郵件</a>
 *   
 *  @since     : 1.0        創建時間:    2013-2-26        下午01:43:56
 *    
 *  TODO     :    實體類
 *
 */
public class User implements Serializable{

    private String name;
    private int age;
    private String email;

    public User() {  //必須有無參構造

    }

    //getter() and setter()   

}


主測試類
復制代碼 代碼如下:

package org.dennisit.reflect.main;
import java.util.HashMap;
import java.util.Map;
import org.dennisit.reflect.entity.User;
/**
 *
 *  ReflectEx.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發送郵件</a>
 *   
 *  @since     : 1.0        創建時間:    2013-2-26        下午01:46:00
 *    
 *  TODO     :    class ReflectEx.java is used for ...
 *
 */
public class ReflectEx {

    public static void main(String[] args)throws Exception {
        Class cls = Class.forName("org.dennisit.reflect.entity.User");
        String className = "org.dennisit.reflect.entity.User";
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("name", "dennisit");
        map.put("age", 22);
        map.put("email", "dennisit@163.com");

        User user = (User)DynamicReflect.getInstance(className, map);
        System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
    }
}


程序運行結果
復制代碼 代碼如下:

dennisit,22,dennisit@163.com

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国内免费精品永久在线视频| 91精品视频免费| 91中文字幕在线| 欧美成人免费视频| 日韩亚洲第一页| 日本久久久久久久久| 日韩专区在线播放| 欧美日韩成人在线视频| 成人国产精品久久久| 亚洲精品综合久久中文字幕| 国产日韩欧美91| 国产成人精品免高潮在线观看| 久久人人看视频| 裸体女人亚洲精品一区| 最近2019中文字幕mv免费看| 国产噜噜噜噜久久久久久久久| 搡老女人一区二区三区视频tv| 日韩精品免费电影| 91精品国产高清久久久久久久久| 精品日韩美女的视频高清| 日韩美女福利视频| 97精品久久久中文字幕免费| 国产情人节一区| 高清日韩电视剧大全免费播放在线观看| 国产日韩综合一区二区性色av| 国产成+人+综合+亚洲欧洲| 久久成人人人人精品欧| 69视频在线播放| 国产精品网址在线| 日韩精品999| 亚洲色图综合久久| 亚洲无亚洲人成网站77777| 国产精品入口尤物| 伊人久久精品视频| 国产亚洲精品美女久久久| 久久久精品电影| 精品国产一区二区在线| 日韩欧美在线字幕| 久久99久久久久久久噜噜| 另类少妇人与禽zozz0性伦| 免费97视频在线精品国自产拍| 日韩有码片在线观看| 久久久伊人日本| 午夜剧场成人观在线视频免费观看| 日韩在线免费高清视频| 欧美高清视频在线播放| 国产精品成人v| 色综合久久中文字幕综合网小说| 亚洲天堂免费在线| 亚洲成人1234| 亚洲加勒比久久88色综合| 亚洲精品www| 欧美午夜视频一区二区| 国产精品第一第二| 久久免费国产精品1| 在线国产精品播放| 欧美日韩电影在线观看| 91视频8mav| 亚洲xxxxx| 亚洲精品乱码久久久久久按摩观| 精品日本高清在线播放| 久久色免费在线视频| 日韩av一区在线| 午夜精品蜜臀一区二区三区免费| 亚洲香蕉av在线一区二区三区| 亚洲高清一二三区| 国产精品视频网站| 国产福利精品在线| 欧美大成色www永久网站婷| 国产精品羞羞答答| 成人精品久久av网站| 一区二区成人av| 亚洲国产精品免费| 5278欧美一区二区三区| 欧美中文字幕在线播放| 自拍偷拍免费精品| 成人精品视频99在线观看免费| 国产精品午夜一区二区欲梦| 精品久久久国产| 国产精品自产拍在线观看| 国产在线一区二区三区| 欧美视频中文字幕在线| 日韩中文字幕精品| 日韩欧美精品中文字幕| 国产精品视频网| 美女av一区二区三区| 国产日产欧美a一级在线| 亚洲电影第1页| 精品国产拍在线观看| 国产精品爽爽ⅴa在线观看| 国产主播精品在线| 亚洲国产成人一区| 亚洲sss综合天堂久久| 欧美日韩黄色大片| 国产91对白在线播放| 91亚洲精品久久久久久久久久久久| 久久久精品久久| 亚洲第一免费网站| 国产精品扒开腿爽爽爽视频| 国产精品一区二区在线| 精品视频偷偷看在线观看| 欧美伦理91i| 亚洲欧美日本精品| 91av视频在线| 日本欧美一二三区| 日韩精品高清在线观看| 国内精品模特av私拍在线观看| www.美女亚洲精品| 欧美成人免费观看| 亚洲日本成人女熟在线观看| 国内精品国产三级国产在线专| 日本一区二区三区在线播放| 久久99久久99精品免观看粉嫩| 国产成人在线一区二区| 精品国产一区二区三区久久久狼| 中文字幕亚洲欧美一区二区三区| 国产在线精品播放| 精品国产精品三级精品av网址| 日韩三级成人av网| 在线观看欧美www| 日韩电影中文字幕| 欧美三级免费观看| 欧美裸体视频网站| 国产91免费看片| 色多多国产成人永久免费网站| 北条麻妃一区二区三区中文字幕| 日本aⅴ大伊香蕉精品视频| 亚洲va久久久噜噜噜久久天堂| 国产色综合天天综合网| 亚洲自拍偷拍网址| 亚洲免费一级电影| 亚洲欧美日韩另类| 成人a在线观看| 日韩av资源在线播放| 日韩av在线免费播放| 91久久久久久久久| 视频在线一区二区| 欧美激情综合色| 国产精品丝袜视频| 国产mv久久久| 久久精品亚洲精品| 日韩免费在线看| 国内伊人久久久久久网站视频| 中文字幕在线观看亚洲| 91超碰中文字幕久久精品| 日韩av电影国产| 韩国三级电影久久久久久| 色偷偷噜噜噜亚洲男人| 欧美电影免费播放| 国产精品扒开腿做爽爽爽的视频| 久久精品视频va| 91久久国产婷婷一区二区| 青草青草久热精品视频在线网站| 国内精品视频在线| 欧美三级欧美成人高清www| 性欧美视频videos6一9| 亚洲a∨日韩av高清在线观看| 亚洲缚视频在线观看| 成人精品久久av网站| 国产精品久久久亚洲| 91嫩草在线视频| 九九视频这里只有精品| 国产精品成人免费视频| 一区二区亚洲欧洲国产日韩|