反射的簡(jiǎn)單使用

反射的簡(jiǎn)單使用

前置條件三個(gè)類(lèi):A 、B:A汇陆、C怒炸;

目標(biāo):分別在獲取 B 和 C 中獲取 A 的 私有變量 以及 調(diào)用私有方法

1. 三個(gè)類(lèi)

  1. A:
package mm.chenme.lib.commutillibdemo.ui.other
open class A {
    private val v1 = 100
    private val v2 = "reflex"

    companion object {
        @JvmStatic
        private fun printStatic(): String {
            println("Hello reflex in static!")
            return "execute complete!\n"
        }
    }

    private fun printNoParam(): String {
        println("Hello reflex without param!")
        return "execute complete!\n"
    }

    private fun printHasParams(param1: String, param2: Int): String {
        println("Hello reflex with params. param1:$param1, param2:$param2")
        return "execute complete!\n"
    }
}
  1. B:
class B : A()
  1. C:
class C

2. 步驟:

  1. 獲取類(lèi) A 的 class,提供以下兩種方法毡代;
val clz = A::class.java
val clz = Class.forName("mm.chenme.lib.commutillibdemo.ui.other.A")

1. 操作私有變量:

  1. 獲取 A 的成員變量阅羹;
val field = clz.getDeclaredField("v2")
  1. 修改訪問(wèn)權(quán)限;
field.isAccessible = true
  1. 獲取 v2 的值并打咏碳拧捏鱼;
println(field.get(this) as String)
// 執(zhí)行結(jié)果:
// reflex
  1. 設(shè)置 v2 的值并打印酪耕;
field.set(this, "Hello reflex!\n")
println(field.get(this) as String)
// 執(zhí)行結(jié)果:
// Hello reflex!

2. 獲取私有函數(shù)并執(zhí)行:

  1. 獲取函數(shù)穷躁;
val method = clz.getDeclaredMethod("printStatic")

getDeclaredMethod() 函數(shù)源碼

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
 throws NoSuchMethodException, SecurityException {
 return getMethod(name, parameterTypes, false);
}

name:要獲取的函數(shù)函數(shù)名稱(chēng)

parameterTypes:要獲取的函數(shù)參數(shù)類(lèi)型的列表(對(duì)于無(wú)參的函數(shù),該可變參數(shù)不寫(xiě))

  1. 修改訪問(wèn)權(quán)限因妇;
method.isAccessible = true
  1. 執(zhí)行該函數(shù)并打印返回值问潭;
println(method.invoke(null) as String)
// 執(zhí)行結(jié)果:
// Hello reflex in static!
// execute complete!

invoke() 函數(shù)源碼

public native Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;

obj:被反射 class 的實(shí)例或其子類(lèi)的實(shí)例(當(dāng)函數(shù)為靜態(tài)函數(shù)時(shí),可以傳 null)婚被;

invoke 函數(shù)參數(shù)1可傳的的數(shù)據(jù)類(lèi)型為:
① clz 的實(shí)例狡忙;
② clz 子類(lèi)的實(shí)例;
③ null址芯;

args :函數(shù)所對(duì)應(yīng)的參數(shù)(對(duì)于無(wú)參的函數(shù)灾茁,該可變參數(shù)不寫(xiě))

3. 類(lèi) B 的完整代碼

class B : A() {
    fun reflexVariable() {
        val clz = A::class.java
        val field = clz.getDeclaredField("v1")
        field.isAccessible = true
        println(field.get(this) as Int)
      
        val field2 = clz.getDeclaredField("v2")
        field2.isAccessible = true
        println(field2.get(this) as String)
        field2.set(this, "Hello reflex!\n")
        println(field2.get(this) as String)
    }
    fun reflexMethod() {
        val clz = A::class.java
      
        /**
         * 靜態(tài)無(wú)參數(shù)函數(shù)反射
         * invoke 函數(shù)參數(shù)1可傳的的數(shù)據(jù)類(lèi)型為:
         * ① clz 的實(shí)例窜觉;
         * ② clz 子類(lèi)的實(shí)例;
         * ③ null
         */
        val method = clz.getDeclaredMethod("printStatic")
        method.isAccessible = true
        println(method.invoke(null) as String)
      
        /**
         * 普通無(wú)參數(shù)函數(shù)反射
         * invoke 函數(shù)參數(shù)1可傳的的數(shù)據(jù)類(lèi)型為:
         * ① clz 的實(shí)例北专;
         * ② clz 子類(lèi)的實(shí)例禀挫;
         */
        val method1 = clz.getDeclaredMethod("printNoParam")
        method1.isAccessible = true
        println(method1.invoke(this) as String)
      
        /**
         * 帶有參數(shù)的函數(shù)反射
         */
        val method2 = clz.getDeclaredMethod("printHasParams", String::clas
        method2.isAccessible = true
        println(method2.invoke(this, "arg1", 100) as String)
    }
}
  • 調(diào)用 reflexVariable()reflexMethod() 執(zhí)行結(jié)果
100
reflex
Hello reflex!

Hello reflex in static!
execute complete!

Hello reflex without param!
execute complete!

Hello reflex with params. param1:arg1, param2:100
execute complete!

4. 在類(lèi) C 中使用反射

  1. 操作變量時(shí),將 get() set() 中的實(shí)例參數(shù)改為 clz.newInstance() 即可拓颓;
println(field.get(this) as Int)
field2.set(this, "Hello reflex!\n")
// 改為
println(field.get(clz.newInstance()) as Int)
field2.set(clz.newInstance(), "Hello reflex!\n")
  1. 在執(zhí)行函數(shù)時(shí)语婴,將 invoke() 中的實(shí)例參數(shù)改為 clz.newInstance() 即可;
println(method1.invoke(this) as String)
println(method2.invoke(this, "arg1", 100) as String)
// 改為
println(method1.invoke(clz.newInstance()) as String)
println(method2.invoke(clz.newInstance(), "arg1", 100) as String)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末驶睦,一起剝皮案震驚了整個(gè)濱河市砰左,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌场航,老刑警劉巖缠导,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異溉痢,居然都是意外死亡僻造,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)孩饼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)髓削,“玉大人,你說(shuō)我怎么就攤上這事捣辆∈呙” “怎么了此迅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵汽畴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我耸序,道長(zhǎng)忍些,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任坎怪,我火速辦了婚禮罢坝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搅窿。我一直安慰自己嘁酿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布男应。 她就那樣靜靜地躺著闹司,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沐飘。 梳的紋絲不亂的頭發(fā)上游桩,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天牲迫,我揣著相機(jī)與錄音,去河邊找鬼借卧。 笑死盹憎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铐刘。 我是一名探鬼主播陪每,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼滨达!你這毒婦竟也來(lái)了奶稠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捡遍,失蹤者是張志新(化名)和其女友劉穎锌订,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體画株,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辆飘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谓传。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜈项。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖续挟,靈堂內(nèi)的尸體忽然破棺而出紧卒,到底是詐尸還是另有隱情,我是刑警寧澤诗祸,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布跑芳,位于F島的核電站,受9級(jí)特大地震影響直颅,放射性物質(zhì)發(fā)生泄漏博个。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一功偿、第九天 我趴在偏房一處隱蔽的房頂上張望盆佣。 院中可真熱鬧,春花似錦械荷、人聲如沸共耍。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)痹兜。三九已至,卻和暖如春关拒,著一層夾襖步出監(jiān)牢的瞬間佃蚜,已是汗流浹背庸娱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谐算,地道東北人熟尉。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洲脂,于是被迫代替她去往敵國(guó)和親斤儿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

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

  • 百度百科 先來(lái)一些不太實(shí)用的解釋?zhuān)篔AVA反射機(jī)制是在運(yùn)行狀態(tài)中恐锦,對(duì)于任意一個(gè)類(lèi)往果,都能夠知道這個(gè)類(lèi)的所有屬性和方法...
    Only凹凸曼閱讀 645評(píng)論 3 10
  • ## 引言 ### java中創(chuàng)建對(duì)象有幾種方式? #### 1.使用new關(guān)鍵字 #### 2.使用clone方...
    芋頭888閱讀 591評(píng)論 1 0
  • 一肮之、概述 Java反射機(jī)制定義 Java反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi)卜录,都能夠知道這個(gè)類(lèi)中的所有屬性和方法...
    CoderZS閱讀 1,642評(píng)論 0 26
  • 1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以讓我們?cè)谶\(yùn)行時(shí)獲取類(lèi)的函數(shù)戈擒、...
    Ten_Minutes閱讀 541評(píng)論 0 4
  • 概述 定義 Java反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi)艰毒,都能夠知道這個(gè)類(lèi)的所有屬性和方法筐高;對(duì)于任意一個(gè)對(duì)象,都...
    JourWon閱讀 323評(píng)論 0 2