快速了解Java反射以及使用場(chǎng)景

反射是一個(gè)很重要的技術(shù)难咕,通過反射技術(shù),能把多個(gè)成分構(gòu)建成一個(gè)Java類距辆,話不多說余佃,開始介紹。

Class類

Class類是一個(gè)比Object類還抽象的應(yīng)該東西跨算,在POJO里面咙冗,Object表示所有的東西,而Class表示這些所有定義對(duì)象的類文件漂彤,可以理解為Class的實(shí)例對(duì)象雾消,表示定義對(duì)象的字節(jié)碼灾搏,Class就是Java的類的抽象。

Class是不能用new來創(chuàng)建的立润,有三種獲得Class實(shí)例的方法狂窑,分別如下

Class a = String.class;
Class b = "abc".getClass();
Class c = Class.forName("java.lang.String");

特殊
有9個(gè)預(yù)定義的Class對(duì)象

byte.class == Byte.TYPE;
short.class == Short.TYPE;
int.class == Integer.TYPE;
long.class == Long.TYPE;;
float.class == Float.TYPE;
double.class == Double.TYPE;
char.class == Character.TYPE;
double.class == Double.TYPE;
boolean.class == Blooean.TYPE;
void.class == Void.TYPE;

原始類型都有各自的Class
Class中有 isPrimitive() 方法來判斷類是否為原始類型
isArray() 判斷是否為數(shù)組

Constructor類

代表類的構(gòu)造器

Class strcla = Class.forName("java.lang.String");
//獲取所有的類的構(gòu)造器
Constructor[] acs = strcla.getConstructors();
//獲取參數(shù)是StringBuffer的構(gòu)造器
Constructor ac = strcla.getConstructor(StringBuffer.class);
// 利用構(gòu)造器,創(chuàng)建對(duì)象
String a = (String) ac.newInstance(new StringBuffer("666"));

這些方法需要捕獲異常

有些構(gòu)造器是私有的桑腮,不能被直接獲取到泉哈,可以暴力反射

public class Demo02 {
    private Demo02(){
        System.out.println("hahaha");
    }
}
public class Demo01 {
    public static void main(String [] args) throws Exception {
        //獲取字節(jié)碼
        Class demo02 = Demo02.class;
        //獲取私有構(gòu)造器
        Constructor c = demo02.getDeclaredConstructor();
        //取消訪問權(quán)限檢查
        c.setAccessible(true);
        //執(zhí)行構(gòu)造器
        c.newInstance();
    }
}
結(jié)果

Method類

方法

public class Demo02 {
    private String secretFunc(String name,String desc) {
        System.out.println(name);
        System.out.println(desc);
        return name + "做了一把" + desc;
    }
}

訪問Demo02實(shí)例的secretFunc方法

class Demo01 {
    public static void main(String [] args) throws Exception {
        Class dclass = Demo02.class;
        //獲取secretFunc方法
        Method method = dclass.getDeclaredMethod("secretFunc",String.class,String.class);
        //實(shí)例一個(gè)demo02
        Demo02 demo02 = new Demo02();
        //去掉權(quán)限驗(yàn)證(暴力反射)
        method.setAccessible(true);
        //執(zhí)行demo02的secretFunc方法,并獲得返回值
        String result = (String) method.invoke(demo02,"羅永浩","錘子");
        //輸出結(jié)果
        System.out.println(result);
    }
}
運(yùn)行結(jié)果

有些方法只知道名字,不知道參數(shù)破讨,可以用getMethods()先取出所有方法丛晦,再一一用,getParameters()來獲得參數(shù)類型提陶。

具體可以去查閱API文檔

Field類

屬性(成員變量)
可以用來訪問私有變量烫沙,修改變量值

public class Demo02 {
    private String XXX = "day day up";
}

修改私有成員變量

class Demo01 {
    public static void main(String [] args) throws Exception {
        Class dclass = Demo02.class;
        //獲取XXX成員變量
        Field xxx = dclass.getDeclaredField("XXX");
        //實(shí)例一個(gè)demo
        Demo02 demo02 = new Demo02();
        //去掉權(quán)限驗(yàn)證(暴力反射)
        xxx.setAccessible(true);
        //獲取這個(gè)屬性的值
        System.out.println(xxx.get(demo02));
        //修改demo02的XXX屬性
        if(xxx.getType()==String.class){
            xxx.set(demo02,"good good study");
        }
        System.out.println(xxx.get(demo02));
    }
}
運(yùn)行結(jié)果

使用場(chǎng)景

在搭建框架的時(shí)候,有時(shí)候不知道需要什么類隙笆,什么方法锌蓄,這個(gè)類有哪些屬性。比如查詢數(shù)據(jù)庫之后的數(shù)據(jù)撑柔,反射成對(duì)象瘸爽。

比如

  • 現(xiàn)在在配置文件中,定義了要使用的類com.User
  • 我們?cè)跀?shù)據(jù)庫里查詢到了一個(gè)數(shù)據(jù)(這里用JSON字符串來代替)
  • 我們根據(jù)配置铅忿,把這組數(shù)據(jù)剪决,轉(zhuǎn)換成配置中的對(duì)象

progress方法是框架定義好的方法,之前讀取配置和查詢數(shù)據(jù)庫分別被我簡(jiǎn)化了

    /**
     * 簡(jiǎn)化讀取配置
     */
    public String getProfileData() {
        return "com.User";
    }

    /**
     * 簡(jiǎn)化數(shù)據(jù)庫查詢(用JSON代替了檀训,JDBC其實(shí)也可以)
     */
    public String getDataFromDatabase() {
        return "{\"address\":\"小米街道\",\"name\":\"雷軍\",\"sex\":\"unknown\"}\n";
    }

    @Test
    public void progress() throws Exception {
        //讀取配置得到對(duì)象配置
        Class useClass = Class.forName(getProfileData());
        //實(shí)例化對(duì)象
        Object needObj = useClass.newInstance();
        //讀取數(shù)據(jù)庫柑潦,獲得數(shù)據(jù)
        JSONObject datas = JSON.parseObject(getDataFromDatabase());
        //獲取參數(shù)名稱集合
        Set<String> keys = datas.keySet();
        for (String key : keys) {
            //調(diào)用set方法
            Method md = useClass.getMethod("set" + StringUtils.capitalize(key), String.class);
            md.invoke(needObj, datas.get(key));
        }
        // 這就得到了需要的對(duì)象
        System.out.println(needObj);
    }

定義好User

package com;
/**
 * Created by zing on 2016/11/10.
 */
public class User {
    private String name;
    private  String address;
    private  String sex;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User對(duì)象:\n" +
                "名字='" + name + "\'\n" +
                "地址='" + address + "\'\n" +
                "性別='" + sex + "\'\n" ;
    }
}

這兩段代碼都搞定之后,執(zhí)行progress方法就可以了肢扯。

執(zhí)行結(jié)果

很明顯妒茬,接下來包裝一下的話担锤,就可以寫一個(gè)自己的持久層框架了蔚晨。

當(dāng)然反射的用處不止這些,我們還可以用這個(gè)來調(diào)用系統(tǒng)的私有方法肛循,Android要是讀過源碼的話铭腕,很多流氓的東西很容易就干出來了(我不是說C++層的),我就不細(xì)說了多糠。

回來

ps:別在意數(shù)據(jù)累舷,重點(diǎn)在技術(shù)
love&peace

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市夹孔,隨后出現(xiàn)的幾起案子被盈,更是在濱河造成了極大的恐慌析孽,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件只怎,死亡現(xiàn)場(chǎng)離奇詭異袜瞬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)身堡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門邓尤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贴谎,你說我怎么就攤上這事汞扎。” “怎么了擅这?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵澈魄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蕾哟,道長(zhǎng)一忱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任谭确,我火速辦了婚禮帘营,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逐哈。我一直安慰自己芬迄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布昂秃。 她就那樣靜靜地躺著禀梳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肠骆。 梳的紋絲不亂的頭發(fā)上算途,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音蚀腿,去河邊找鬼嘴瓤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛莉钙,可吹牛的內(nèi)容都是我干的廓脆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼磁玉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼停忿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蚊伞,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤席赂,失蹤者是張志新(化名)和其女友劉穎吮铭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颅停,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沐兵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了便监。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扎谎。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖烧董,靈堂內(nèi)的尸體忽然破棺而出毁靶,到底是詐尸還是另有隱情,我是刑警寧澤逊移,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布预吆,位于F島的核電站,受9級(jí)特大地震影響胳泉,放射性物質(zhì)發(fā)生泄漏拐叉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一扇商、第九天 我趴在偏房一處隱蔽的房頂上張望凤瘦。 院中可真熱鬧,春花似錦案铺、人聲如沸蔬芥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笔诵。三九已至,卻和暖如春姑子,著一層夾襖步出監(jiān)牢的瞬間乎婿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工街佑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谢翎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓舆乔,卻偏偏與公主長(zhǎng)得像岳服,于是被迫代替她去往敵國和親剂公。 傳聞我的和親對(duì)象是個(gè)殘疾皇子希俩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)纲辽,斷路器颜武,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法璃搜,類相關(guān)的語法,內(nèi)部類的語法鳞上,繼承相關(guān)的語法这吻,異常的語法,線程的語...
    子非魚_t_閱讀 31,625評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在篙议,面了一些公司唾糯,掛了不少,但最終還是拿到小米鬼贱、百度移怯、阿里、京東这难、新浪舟误、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評(píng)論 11 349
  • 這是我做的一個(gè)Html測(cè)試頁面: 頁面效果如下所示: html代碼如下所示 這是另外一個(gè)html頁面 html代碼...
    EchoHK閱讀 332評(píng)論 0 1
  • “媽媽,你看蹋岩,我的斑馬褲!”一回到家赖草,芳芳就指著身上的褲子得意地說,這是外公外婆從老家來北京“接班”的第二天(雙方...
    豆迪閱讀 300評(píng)論 0 1