欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java反射機(jī)制的實(shí)現(xiàn)詳解

 更新時(shí)間:2013年05月06日 17:11:40   作者:  
反射主要解決動(dòng)態(tài)編程,即使用反射時(shí),所有的對(duì)象生成是動(dòng)態(tài)的,因此調(diào)用的方法也是動(dòng)態(tài)的.反射可以簡(jiǎn)化開發(fā),但是代碼的可讀性很低

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


與反射有關(guān)的類包.

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


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


如何獲得Class對(duì)象

復(fù)制代碼 代碼如下:

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

每種類型的Class對(duì)象只有一個(gè),即他們的地址只有一個(gè),但是不同類型是不同的.

所以下面的打印結(jié)果都為true.

復(fù)制代碼 代碼如下:

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

反射獲取類中的成員的相關(guān)方法

[獲取構(gòu)造<根據(jù)參數(shù)類型>](使用時(shí)一般用不帶declared)

復(fù)制代碼 代碼如下:

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

[獲取屬性<根據(jù)屬性名>](使用時(shí)一般用是帶declared,因?yàn)閷傩砸话愣际撬接械?/SPAN>)
復(fù)制代碼 代碼如下:

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

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

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

注意:

new Instance()調(diào)用的是無參構(gòu)造,如果該類沒有無參構(gòu)造方法,則newInstance()會(huì)產(chǎn)生異常.

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

因此取屬性的時(shí)候一般來說是帶declared的,因?yàn)閷傩砸话愣际撬接械?取方法時(shí)一般是不帶declared的,取構(gòu)造時(shí)一般也是不帶declared的.

實(shí)例模擬反射獲取類中的相關(guān)屬性和方法

利用反射對(duì)屬性賦值

Field中的方法

 Object get(Object obj)

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

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

      值 = f.get(對(duì)象);

 void set(Object obj, Object value)

  將指定對(duì)象變量上此 Field 對(duì)象表示的字段設(shè)置為指定的新值。

  f.set(對(duì)象,值);

 Class<?> getType()

  返回一個(gè) Class 對(duì)象,它標(biāo)識(shí)了此 Field 對(duì)象所表示字段的聲明類型。

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

復(fù)制代碼 代碼如下:

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

利用反射調(diào)用構(gòu)造

對(duì)于構(gòu)造真正調(diào)用是在調(diào)用newInstance()方法時(shí).

復(fù)制代碼 代碼如下:

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

利用反射調(diào)用方法

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

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

m.invoke(對(duì)象,方法調(diào)用的參數(shù) )如果底層方法所需的形參數(shù)為 0,則所提供的 args 數(shù)組長(zhǎng)度可以為 0 或 null。

復(fù)制代碼 代碼如下:

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

反射應(yīng)用實(shí)例

實(shí)體類

復(fù)制代碼 代碼如下:

package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
 *
 *  User.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發(fā)送郵件</a>
 *   
 *  @since     : 1.0        創(chuàng)建時(shí)間:    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);
    }
}


反射測(cè)試類
復(fù)制代碼 代碼如下:

package org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
 *
 *  ReflectEx.java   
 *
 *  @version : 1.1
 * 
 *  @author  : 蘇若年    <a href="mailto:DennisIT@163.com">發(fā)送郵件</a>
 *   
 *  @since     : 1.0        創(chuàng)建時(shí)間:    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();       //創(chuàng)建User的對(duì)象
        Field f = cls.getDeclaredField("test");    //獲取test屬性
        f.setAccessible(true);                    //打開私有屬性test的訪問權(quán)限
        f.set(obj, "zhangsan");                    //為test重新復(fù)制
        System.out.println(f.get(obj));            //獲取obj的test屬性值
        //根據(jù)方法名execute獲取方法
        java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
        m.invoke(obj, "dennisit",23);            //調(diào)用execute方法
    }
}


運(yùn)行效果
復(fù)制代碼 代碼如下:

zhangsan
name=dennisit,age=23

編寫一個(gè)反射動(dòng)態(tài)實(shí)例化類的例子
復(fù)制代碼 代碼如下:

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">發(fā)送郵件</a>
 *   
 *  @since     : 1.0        創(chuàng)建時(shí)間:    2013-2-26        下午01:58:12
 *    
 *  TODO     :    利用反射動(dòng)態(tài)實(shí)例化的例子
 *
 */
public class DynamicReflect {

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


接下來我們測(cè)試我們編寫的動(dòng)態(tài)反射實(shí)例化例子

實(shí)體類

復(fù)制代碼 代碼如下:

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

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

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

    }

    //getter() and setter()   

}


主測(cè)試類
復(fù)制代碼 代碼如下:

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">發(fā)送郵件</a>
 *   
 *  @since     : 1.0        創(chuàng)建時(shí)間:    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());
    }
}


程序運(yùn)行結(jié)果
復(fù)制代碼 代碼如下:

dennisit,22,dennisit@163.com

相關(guān)文章

  • Java使用ES?Client?調(diào)用滾動(dòng)查詢及Elasticsearch滾動(dòng)查詢Scrolling機(jī)制

    Java使用ES?Client?調(diào)用滾動(dòng)查詢及Elasticsearch滾動(dòng)查詢Scrolling機(jī)制

    Elasticsearch提供了一種稱為"滾動(dòng)查詢"(Scrolling)的機(jī)制,用于處理大型數(shù)據(jù)集的分頁(yè)查詢,這篇文章給大家介紹滾動(dòng)查詢的一般步驟及Java使用ESClient調(diào)用滾動(dòng)查詢的方法,感興趣的朋友一起看看吧
    2023-08-08
  • SpringBoot?如何從容器中獲取對(duì)象

    SpringBoot?如何從容器中獲取對(duì)象

    這篇文章主要介紹了SpringBoot?如何從容器中獲取對(duì)象,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    這篇文章主要介紹了SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法

    Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法

    Java中可以通過Thread類和Runnable接口來創(chuàng)建多個(gè)線程,下面這篇文章主要給大家介紹了關(guān)于Java基礎(chǔ)之多線程方法狀態(tài)和創(chuàng)建方法的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • 分享幾個(gè)提高Java性能的高效用法

    分享幾個(gè)提高Java性能的高效用法

    這篇文章主要介紹了分享幾個(gè)提高Java性能的高效用法 ,需要的朋友可以參考下
    2014-10-10
  • Java實(shí)現(xiàn)網(wǎng)絡(luò)資源的單線程下載

    Java實(shí)現(xiàn)網(wǎng)絡(luò)資源的單線程下載

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)在一個(gè)線程中完成網(wǎng)絡(luò)資源的下載,文中的實(shí)現(xiàn)步驟講解詳細(xì),感興趣的可以嘗試下
    2022-10-10
  • Spring security中的授權(quán)

    Spring security中的授權(quán)

    本篇為大家?guī)鞸pring security的授權(quán),首先要理解一些概念,有關(guān)于:權(quán)限、角色、安全上下文、訪問控制表達(dá)式、方法級(jí)安全性、訪問決策管理器,這篇文章主要介紹了Spring security中的授權(quán),需要的朋友可以參考下
    2024-01-01
  • Mybatis的Cursor避免OOM異常的方法詳解

    Mybatis的Cursor避免OOM異常的方法詳解

    在Mybatis中,有一個(gè)特殊的對(duì)象Cursor,這個(gè)對(duì)象的注釋上清晰的說明了,這個(gè)類的用途,在Mybatis中使用Cursor非常簡(jiǎn)單,只要在Mapper文件中將方法的返回值設(shè)置成Cursor<T>即可,本文給大家介紹了Mybatis的Cursor避免OOM異常的方法,需要的朋友可以參考下
    2024-06-06
  • Java實(shí)現(xiàn)MD5加密的方法

    Java實(shí)現(xiàn)MD5加密的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)MD5加密的方法,實(shí)例分析了基于java實(shí)現(xiàn)md5加密的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • java樂觀鎖原理與實(shí)現(xiàn)案例分析

    java樂觀鎖原理與實(shí)現(xiàn)案例分析

    這篇文章主要介紹了java樂觀鎖原理與實(shí)現(xiàn),結(jié)合具體案例形式分析了樂觀鎖的原理及java使用樂觀鎖實(shí)現(xiàn)自動(dòng)派單功能的相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10

最新評(píng)論