黑馬程序員-反射

反射

1.Class類

  • Class類:Java程序中的各個(gè)Java類屬于同一類事物豆巨,描述這類事物的Java類名就是Class前域。
  • Class描述了:類的名字彻亲,類的訪問屬性,類所屬包名已慢,字段名稱的列表,方法名稱的列表等霹购。
  • 類的字節(jié)碼實(shí)例對(duì)象信息獲取方式:Class主要是獲取Java類的字節(jié)碼信息在獲取各個(gè)Java類詳細(xì)信息佑惠,需要Java類從硬盤加載到內(nèi)存中,獲取方式有:Class class = Dtae.class;齐疙、Class.forName("java.lang.String");膜楷、對(duì)象.getClass()
  • 在源程序中出現(xiàn)的類型贞奋,都有各自的Class實(shí)例對(duì)象*
        String str = "abc";
        Class cls1 = str.getClass();
        Class cls2 = String.class;
        Class cls3 = Class.forName("java.lang.String");
        System.out.println(cls1.isPrimitive()); //是否是基本數(shù)據(jù)類型
        System.out.println(int.class == Integer.TYPE); //int包裝數(shù)據(jù)類型類的類型和int對(duì)應(yīng)的字節(jié)碼相同
        System.out.println(int.class == Integer.class); //int和Integer的字節(jié)碼不相同
        System.out.println(int[].class.isArray()); //數(shù)組類型的Class實(shí)例對(duì)象

2.反射介紹

  • 反射就是把Java類中的各種成分映射成相應(yīng)的Java類赌厅。
  • 一個(gè)類中的每個(gè)成員都可以用相應(yīng)的反射類的一個(gè)實(shí)例對(duì)象來表示,如類中的方法可以用Method對(duì)象來表示轿塔。

構(gòu)造方法的反射:

        Constructor[] con = Class.forName("java.lang.String").getConstructors();//獲取此類的所有構(gòu)造方法
        Constructor con1 = String.class.getConstructor(StringBuffer.class);//獲取單個(gè)指定構(gòu)造方法
  • 創(chuàng)建構(gòu)造方法:String str = (String)con1.newInstance(new StringBuffer("bac"));////創(chuàng)建new String(new StringBuffer("abc"))此對(duì)象,Class.newInstance()用來創(chuàng)建默認(rèn)的構(gòu)造方法特愿。

成員變量的反射:

package com.sergio.NewTecl;

import java.io.File;
import java.lang.reflect.Field;

/**
 * 成員反射
 * Created by Sergio on 2015-06-05.
 */
public class ReflectField {
    public static void main(String[] args) throws Exception {
        ReflectTest rt = new ReflectTest(3, 5);
        //獲取rt字節(jié)碼對(duì)象上的x變量值.獲取私有變量的值
        Field fieldX = rt.getClass().getDeclaredField("x");
        //設(shè)置私有變量獲取后可以使用了
        fieldX.setAccessible(true);
        System.out.println(fieldX.get(rt));
        //獲取的是共有變量
        Field fieldY = rt.getClass().getField("y");
        System.out.println(fieldY.get(rt));

        changeStringValue(rt);
        System.out.println(rt);
    }

    //更改rt對(duì)象中變量的某些值
    private static void changeStringValue(Object object) throws IllegalAccessException {
        Field[] fields = object.getClass().getFields();
        for (Field field : fields) {
            if (field.getType() == String.class) {
                String oldValue = (String) field.get(object);
                String newValue = oldValue.replace('b', 'a');
                field.set(object, newValue);
            }
        }
    }
}


class ReflectTest {
    private int x;
    public int y;
    //更改b為a
    public String str1 = "ball";
    public String str2 = "basketball";
    public String str3 = "itcast";


    public ReflectTest(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "ReflectTest{ + str1='" + str1 + '\'' + ", str2='" + str2 + '\'' + ", str3='" + str3
            + '\'' +
            '}';
    }
}

成員方法反射

        String str1 = "abc";
        //str1.charAt(1)調(diào)用下面方法方式
        Method method = String.class.getMethod("charAt", int.class);
        //打印1位置的字符,method.invoke(null, 1)靜態(tài)方法調(diào)用
        System.out.println(method.invoke(str1, 1));

數(shù)組的反射

  • 具有相同維數(shù)和元素類型的數(shù)組屬于同一個(gè)類型勾缭,即具有相同的Class實(shí)例對(duì)象揍障。
  • 基本類型的一維數(shù)組可以被當(dāng)作Object類型使用,但不能當(dāng)作Object[]類型使用漫拭;非基本類型的一維數(shù)組亚兄,既可以當(dāng)作Object類型使用,又可以當(dāng)作Object[]類型使用采驻。
package com.sergio.NewTecl;

import java.lang.reflect.Array;

/**
 * 數(shù)組反射實(shí)例
 * Created by Sergio on 2015-06-06.
 */
public class ReflectArrayTest {
    public static void main(String[] args) {
        int[] a1 = new int[] {1, 2, 3};
        String[] a4 = new String[] {"xya"};

        printObject(a1);
        printObject(a4);

    }
    //打印數(shù)組中的元素
    private static void printObject(Object obj) {
        Class clazz = obj.getClass();
        if (clazz.isArray()) {
            int length = Array.getLength(obj);
            for (int i = 0; i < length; i++) {
                System.out.println(Array.get(obj, i));
            }
        } else {
            System.out.println(obj);
        }
    }
}
類加載器與反射
  • 類加載器是用來加載外部配置文件的主要方式之一审胚。
package com.sergio.NewTecl;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

/**
 * 反射加載外部文件操作
 * Created by Sergio on 2015-06-06.
 */
public class ReflectCollection {
    public static void main(String[] args) throws Exception {
        //        Collection collections = new ArrayList<>();
        InputStream ips = new FileInputStream("config.properties");
        //類加載方法,加載外部文件配置的主要方式
        //InputStream ips2 = ReflectCollection.class.getClassLoader().getResourceAsStream("config.properties");

        Properties props = new Properties();
        props.load(ips);
        ips.close();

        String className = props.getProperty("className");
        //創(chuàng)建ArrayList構(gòu)造方法實(shí)例礼旅,加載的外部文件為className=java.util.ArrayList
        Collection collections = (Collection) Class.forName(className).newInstance();
        ReflectTest rt = new ReflectTest(3, 5);
        ReflectTest rt1 = new ReflectTest(3, 5);
        ReflectTest rt2 = new ReflectTest(3, 5);
        collections.add(rt);
        collections.add(rt1);
        collections.add(rt2);

        System.out.println(collections.size());
    }
}


class ReflectTest1 {
    private int x;
    public int y;

    public ReflectTest1(int x, int y) {
        this.x = x;
        this.y = y;
    }
}


配置文件信息:className=java.util.ArrayList

反射與泛型

  • 通過制定對(duì)應(yīng)的Class對(duì)象膳叨,程序可以獲得該類里面所有的Field,不管該Field使用private方法或者public獲得Field對(duì)象后都可以使用getType()來獲取其類型痘系。Class<?> type= f.getType()獲得字段的類型菲嘴,此方法
    只對(duì)普通Field有效,若該Field有泛型修飾汰翠,則不能準(zhǔn)確得到該Field的泛型參數(shù)龄坪,如Map<String, Integer>;,為了獲得指定Fild的泛型類型,可以如下:Type type = f.getGenerciType()得到泛型類型复唤,然后將Type對(duì)象強(qiáng)轉(zhuǎn)為ParameterizedType健田,表示增加泛型后的類型。Type getRawType()返回被泛型限制的類型佛纫。Type[] getActualArguments()返回泛型原始參數(shù)類型妓局。
  • 反射獲取泛型類型(信息)的步驟:
    1. 獲取當(dāng)前類
    2. 獲取目標(biāo)字段
    3. 獲取包含泛型類型的類型getGenericType()
    4. 強(qiáng)轉(zhuǎn)至子類ParameterizedType总放,因?yàn)門ype沒有任何對(duì)應(yīng)的方法
    5. 獲得泛型真正的類型getActualTypeArguments()
package com.sergio.NewTecl;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Vector;

/**
 * 通過反射獲取泛型方法的參數(shù)類型
 * Created by Sergio on 2015-06-12.
 */
public class GenericDao {
    public static void applyVector(Vector<Date> v1) {

    }

    public static void main(String[] args) throws Exception {
        //要調(diào)用哪個(gè)泛型方法
        Method method = GenericDao.class.getMethod("applyVector()", Vector.class);
        Type[] types = method.getGenericParameterTypes();//獲取泛型方法
        ParameterizedType pType = (ParameterizedType) types[0];//轉(zhuǎn)化為參數(shù)類型
        System.out.println(pType.getRawType());//返回被限制的泛型類型
        System.out.println(pType.getActualTypeArguments());////返回泛型實(shí)際參數(shù)類型
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市好爬,隨后出現(xiàn)的幾起案子局雄,更是在濱河造成了極大的恐慌,老刑警劉巖存炮,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炬搭,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡僵蛛,警方通過查閱死者的電腦和手機(jī)尚蝌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來充尉,“玉大人,你說我怎么就攤上這事衣形⊥障溃” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵谆吴,是天一觀的道長(zhǎng)倒源。 經(jīng)常有香客問我,道長(zhǎng)句狼,這世上最難降的妖魔是什么笋熬? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮腻菇,結(jié)果婚禮上胳螟,老公的妹妹穿的比我還像新娘。我一直安慰自己筹吐,他們只是感情好糖耸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丘薛,像睡著了一般嘉竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洋侨,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天舍扰,我揣著相機(jī)與錄音,去河邊找鬼希坚。 笑死边苹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吏够。 我是一名探鬼主播勾给,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼滩报,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了播急?” 一聲冷哼從身側(cè)響起脓钾,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎桩警,沒想到半個(gè)月后可训,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捶枢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年握截,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烂叔。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谨胞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒜鸡,到底是詐尸還是另有隱情胯努,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布逢防,位于F島的核電站叶沛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忘朝。R本人自食惡果不足惜灰署,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望局嘁。 院中可真熱鬧溉箕,春花似錦、人聲如沸导狡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)旱捧。三九已至独郎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間枚赡,已是汗流浹背氓癌。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贫橙,地道東北人贪婉。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像卢肃,于是被迫代替她去往敵國(guó)和親疲迂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子才顿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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