圍繞Java反射,BAT的面試官可以問(wèn)出多少花樣

好久不見(jiàn),在疫情的控制下,我急需一杯奶茶續(xù)續(xù)命寇蚊!

作者:王炸 |【堅(jiān)持1000篇原創(chuàng)】

2020.2.21 王炸的第60篇原創(chuàng)

??先贊后看是技術(shù)人的傳統(tǒng)美德??

有小朋友問(wèn)我笔时,我剛剛學(xué)Java,沒(méi)接觸過(guò)項(xiàng)目仗岸,也沒(méi)機(jī)會(huì)用Spring之類(lèi)的框架允耿,看書(shū)也知道反射都有什么內(nèi)容,哪本書(shū)都說(shuō)反射很有用扒怖,但到現(xiàn)在都不知道它用在啥上面较锡,所有,反射有啥用盗痒?

關(guān)于反射蚂蕴,我必須要吐槽一下,初學(xué)的時(shí)候如果靠看xxx從入門(mén)到精通系列的書(shū)俯邓,理解反射可太TM困難了骡楼,看的我懷疑人生,那個(gè)時(shí)候我一度懷疑稽鞭,我該不是個(gè)智障吧鸟整!

今天來(lái)分析下:圍繞Java反射,BAT的面試官可以問(wèn)出多少花樣朦蕴。

反射關(guān)系到Java的語(yǔ)言特性篮条,jvm的內(nèi)存細(xì)節(jié)

JVM:只能跑Java代碼的CPU

剛剛開(kāi)始我也不理解Java的虛擬機(jī)到底算個(gè)什么東西?

第一節(jié)接觸這東西一臉困惑吩抓,字節(jié)碼代碼是在CPU上執(zhí)行涉茧?在虛擬機(jī)上執(zhí)行?虛擬機(jī)又是個(gè)什么東西疹娶?

后來(lái)我慢慢試著理解:JVM就是跑才CPU上的一個(gè)虛擬CPU降瞳,但是這個(gè)CPU只能跑Java代碼

Java之所以能跨平臺(tái)就是因?yàn)檫@個(gè)東西,你可以理解成一個(gè)進(jìn)程,程序挣饥,只不過(guò)他的作用是用來(lái)跑你的代碼的除师。

上圖是java的內(nèi)存模型,我們關(guān)注的點(diǎn)扔枫,一個(gè)方法區(qū)汛聚,一個(gè)棧,一個(gè)堆短荐,初學(xué)的時(shí)候老師不深入的話只告訴你java的內(nèi)存分為堆和棧

假如你寫(xiě)了一段代碼:String s=new String();

運(yùn)行了起來(lái)倚舀!這里面發(fā)生了什么?

  • 首先JVM會(huì)啟動(dòng)忍宋,你的代碼會(huì)編譯成一個(gè)xxx.class文件痕貌。

  • 然后被類(lèi)加載器加載進(jìn)jvm的內(nèi)存中(虛擬CPU),你的類(lèi)Object加載到方法區(qū)中糠排,創(chuàng)建了Object類(lèi)的class對(duì)象到堆中舵稠,注意這個(gè)不是new出來(lái)的對(duì)象,而是類(lèi)的類(lèi)型對(duì)象入宦,每個(gè)類(lèi)只有一個(gè)class對(duì)象哺徊,作為方法區(qū)類(lèi)的數(shù)據(jù)結(jié)構(gòu)的接口。

    ??注意:jvm創(chuàng)建對(duì)象前乾闰,會(huì)先檢查類(lèi)是否加載落追,尋找類(lèi)對(duì)應(yīng)的class對(duì)象,若加載好涯肩,則為你的對(duì)象分配內(nèi)存轿钠,初始化也就是代碼:new Object()。

  • 上面的流程就是你自己寫(xiě)好的代碼扔給jvm去跑病苗,跑完就over了谣膳,jvm關(guān)閉,你的程序也停止了铅乡。

    為什么會(huì)發(fā)明反射這種技術(shù)继谚?

    想想上面的程序?qū)ο笫亲约簄ew的,程序相當(dāng)于寫(xiě)死了給jvm去跑阵幸,程序員都是聰明的動(dòng)物花履,還有沒(méi)有更好的辦吧不用寫(xiě)死,不用new挚赊。

    假如一個(gè)服務(wù)器上突然遇到某個(gè)請(qǐng)求哦要用到某個(gè)類(lèi)诡壁,哎呀但沒(méi)加載進(jìn)jvm,是不是要停下來(lái)自己寫(xiě)段代碼荠割,new一下妹卿,哦啟動(dòng)一下服務(wù)器旺矾,(腦殘)!

    這個(gè)時(shí)候反射技術(shù)誕生了夺克,這在當(dāng)時(shí)箕宙,是一個(gè)非常先進(jìn)的理念,Java也因此得到更多人認(rèn)可铺纽。

    反射是什么呢柬帕?

    當(dāng)我們的程序在運(yùn)行時(shí),需要?jiǎng)討B(tài)的加載一些類(lèi)這些類(lèi)可能之前用不到所以不用加載到j(luò)vm狡门,而是在運(yùn)行時(shí)根據(jù)需要才加載陷寝,這樣的好處對(duì)于服務(wù)器來(lái)說(shuō)不言而喻。

    Java的反射機(jī)制是在編譯并不確定是哪個(gè)類(lèi)被加載了其馏,而是在程序運(yùn)行的時(shí)候才加載凤跑、探知、自審叛复。使用在編譯期并不知道的類(lèi)仔引。這樣的特點(diǎn)就是反射。

    有兩個(gè)程序員致扯,一個(gè)程序員在寫(xiě)程序的時(shí)候肤寝,需要使用第二個(gè)程序員所寫(xiě)的類(lèi)当辐,但第二個(gè)程序員并沒(méi)完成他所寫(xiě)的類(lèi)抖僵,這時(shí)第一個(gè)程序員不能通過(guò)編譯,但是利用反射就可以通過(guò)缘揪。原因是java的反射機(jī)制它知道類(lèi)的基本結(jié)構(gòu)耍群,這種對(duì)Java類(lèi)結(jié)構(gòu)探知的能力,我們稱(chēng)為Java類(lèi)的“自審”找筝。

    舉個(gè)例子:

    我們的項(xiàng)目底層有時(shí)是用Mysql蹈垢,有時(shí)用oracle,需要?jiǎng)討B(tài)地根據(jù)實(shí)際情況加載驅(qū)動(dòng)類(lèi)袖裕,這個(gè)時(shí)候反射就有用了曹抬。

    假設(shè) com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection這兩個(gè)類(lèi)我們要用急鳄。

    這時(shí)候我們的程序就寫(xiě)得比較動(dòng)態(tài)化谤民,通過(guò)Class tc = Class.forName("com.java.dbtest.TestConnection");

    通過(guò)類(lèi)的全類(lèi)名讓jvm在服務(wù)器中找到并加載這個(gè)類(lèi),而如果是oracle則傳入的參數(shù)就變成另一個(gè)了疾宏。

    這時(shí)候就可以看到反射的好處了张足,這個(gè)動(dòng)態(tài)性就體現(xiàn)出java的特性了!

    舉多個(gè)例子坎藐,大家如果接觸過(guò)spring为牍,會(huì)發(fā)現(xiàn)當(dāng)你配置各種各樣的bean時(shí),是以配置文件的形式配置的,你需要用到哪些bean就配哪些碉咆,spring容器就會(huì)根據(jù)你的需求去動(dòng)態(tài)加載抖韩,你的程序就能健壯地運(yùn)行。

    好吧吟逝,圍繞Java反射帽蝶,BAT的面試官可以問(wèn)出多少花樣

    面試:Java反射機(jī)制在Spring IOC中的應(yīng)用

    IOC:即“控制反轉(zhuǎn)”,不是什么技術(shù)块攒,而是一種思想励稳。

    使用IOC意味著將你設(shè)計(jì)好的對(duì)象交給容器控制,而不是傳統(tǒng)的在你的對(duì)象內(nèi)部直接控制囱井。

    IOC底層實(shí)現(xiàn)的原理(反射)驹尼,Bean容器的實(shí)現(xiàn),就不對(duì)IOC的概念進(jìn)行詳述了庞呕。

    在Spring的配置文件中新翎,經(jīng)常看到如下配置:

    <bean id="courseDao" class="com.qcjy.learning.Dao.impl.CourseDaoImpl"></bean>

    那么通過(guò)這樣配置住练,Spring是怎么幫我們實(shí)例化對(duì)象地啰,并且放到容器中去了了?對(duì)讲逛,就是通過(guò)反射?髁摺!盏混!

    面試:Java反射在動(dòng)態(tài)代理中的應(yīng)用

    JDK動(dòng)態(tài)代理

    Java動(dòng)態(tài)代理類(lèi)位于Java.lang.reflect包下蔚鸥,一般主要涉及到以下兩個(gè)類(lèi):

  • Interface InvocationHandler:該接口中僅定義了一個(gè)方法Object,invoke(Object obj,Method method, Object[] args)许赃。在實(shí)際使用時(shí)止喷,第一個(gè)參數(shù)obj一般是指代理類(lèi),method是被代理的方法混聊,如上例中的request()弹谁,args為該方法的參數(shù)數(shù)組。這個(gè)抽象方法在代理類(lèi)中動(dòng)態(tài)實(shí)現(xiàn)句喜。

  • Proxy:該類(lèi)即為動(dòng)態(tài)代理類(lèi)预愤。

  • Cglib動(dòng)態(tài)代理

    JDK的動(dòng)態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類(lèi),而不能實(shí)現(xiàn)接口的類(lèi)就不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理藤滥,cglib是針對(duì)類(lèi)來(lái)實(shí)現(xiàn)代理的鳖粟,他的原理是對(duì)指定的目標(biāo)類(lèi)生成一個(gè)子類(lèi),并覆蓋其中方法實(shí)現(xiàn)增強(qiáng)拙绊,但因?yàn)椴捎玫氖抢^承向图,所以不能對(duì)final修飾的類(lèi)進(jìn)行代理泳秀。JDK代理要求被代理的類(lèi)必須實(shí)現(xiàn)接口,有很強(qiáng)的局限性榄攀。而CGLIB動(dòng)態(tài)代理則沒(méi)有此類(lèi)強(qiáng)制性要求嗜傅。簡(jiǎn)單的說(shuō),CGLIB會(huì)讓生成的代理類(lèi)繼承被代理類(lèi)檩赢,并在代理類(lèi)中對(duì)代理方法進(jìn)行強(qiáng)化處理(前置處理吕嘀、后置處理等)。在CGLIB底層贞瞒,其實(shí)是借助了ASM這個(gè)非常強(qiáng)大的Java字節(jié)碼生成框架偶房。

    Javassist代理

    一種是使用代理工廠創(chuàng)建,另一種通過(guò)使用動(dòng)態(tài)代碼創(chuàng)建军浆。使用代理工廠創(chuàng)建時(shí)棕洋,方法與CGLIB類(lèi)似,也需要實(shí)現(xiàn)一個(gè)用于代理邏輯處理的Handler乒融;使用動(dòng)態(tài)代碼創(chuàng)建掰盘,生成字節(jié)碼,這種方式可以非常靈活赞季,甚至可以在運(yùn)行時(shí)生成業(yè)務(wù)邏輯愧捕。

    vx搜索:轉(zhuǎn)行程序員

    vx搜索:轉(zhuǎn)行程序員

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
    • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市申钩,隨后出現(xiàn)的幾起案子次绘,更是在濱河造成了極大的恐慌,老刑警劉巖典蜕,帶你破解...
      沈念sama閱讀 219,188評(píng)論 6 508
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件断盛,死亡現(xiàn)場(chǎng)離奇詭異罗洗,居然都是意外死亡愉舔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 93,464評(píng)論 3 395
    • 文/潘曉璐 我一進(jìn)店門(mén)伙菜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)轩缤,“玉大人,你說(shuō)我怎么就攤上這事贩绕』鸬模” “怎么了?”我有些...
      開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
    • 文/不壞的土叔 我叫張陵淑倾,是天一觀的道長(zhǎng)馏鹤。 經(jīng)常有香客問(wèn)我,道長(zhǎng)娇哆,這世上最難降的妖魔是什么湃累? 我笑而不...
      開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
    • 正文 為了忘掉前任勃救,我火速辦了婚禮,結(jié)果婚禮上治力,老公的妹妹穿的比我還像新娘蒙秒。我一直安慰自己,他們只是感情好宵统,可當(dāng)我...
      茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
    • 文/花漫 我一把揭開(kāi)白布晕讲。 她就那樣靜靜地躺著,像睡著了一般马澈。 火紅的嫁衣襯著肌膚如雪瓢省。 梳的紋絲不亂的頭發(fā)上,一...
      開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
    • 那天痊班,我揣著相機(jī)與錄音净捅,去河邊找鬼。 笑死辩块,一個(gè)胖子當(dāng)著我的面吹牛蛔六,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播废亭,決...
      沈念sama閱讀 40,430評(píng)論 3 420
    • 文/蒼蘭香墨 我猛地睜開(kāi)眼国章,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了豆村?” 一聲冷哼從身側(cè)響起液兽,我...
      開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
    • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掌动,沒(méi)想到半個(gè)月后四啰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
      沈念sama閱讀 45,801評(píng)論 1 317
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粗恢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
    • 正文 我和宋清朗相戀三年柑晒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眷射。...
      茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
    • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匙赞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妖碉,到底是詐尸還是另有隱情涌庭,我是刑警寧澤,帶...
      沈念sama閱讀 35,804評(píng)論 5 346
    • 正文 年R本政府宣布欧宜,位于F島的核電站坐榆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏冗茸。R本人自食惡果不足惜席镀,卻給世界環(huán)境...
      茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
    • 文/蒙蒙 一羹铅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愉昆,春花似錦职员、人聲如沸。這莊子的主人今日做“春日...
      開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至芳室,卻和暖如春专肪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堪侯。 一陣腳步聲響...
      開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
    • 我被黑心中介騙來(lái)泰國(guó)打工嚎尤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伍宦。 一個(gè)月前我還...
      沈念sama閱讀 48,365評(píng)論 3 373
    • 正文 我出身青樓芽死,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親次洼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子关贵,可洞房花燭夜當(dāng)晚...
      茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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