1
更新于2019-10-24 08:40:22
5535
閱讀
2
回復(fù)
花了近十年的時(shí)間,整理出史上最全面Java面試題
 
1、String 是最基本的數(shù)據(jù)類型嗎?

不是。Java中的基本數(shù)據(jù)類型只有8個(gè):byte、short、int、long、float、double、char、boolean;除了基本類型(primitive type)和枚舉類型(enumeration type),剩下的都是引用類型(reference type)。

2、float f=3.4;是否正確?

不正確。3.4是雙精度數(shù),將雙精度型(double)賦值給浮點(diǎn)型(float)屬于下轉(zhuǎn)型(down-casting,也稱為窄化)會(huì)造成精度損失,因此需要強(qiáng)制類型轉(zhuǎn)換float f =(float)3.4; 或者寫成float f =3.4F;。

3、short s1 = 1; s1 = s1 + 1;有錯(cuò)嗎?short s1 = 1; s1 += 1;有錯(cuò)嗎?

對(duì)于short s1 = 1; s1 = s1 + 1;由于1是int類型,因此s1+1運(yùn)算結(jié)果也是int 型,需要強(qiáng)制轉(zhuǎn)換類型才能賦值給short型。而short s1 = 1; s1 += 1;可以正確編譯,因?yàn)閟1+= 1;相當(dāng)于s1 = (short)(s1 + 1);其中有隱含的強(qiáng)制類型轉(zhuǎn)換。

4、int和Integer有什么區(qū)別?

Java是一個(gè)近乎純潔的面向?qū)ο缶幊陶Z(yǔ)言,但是為了編程的方便還是引入了基本數(shù)據(jù)類型,但是為了能夠?qū)⑦@些基本數(shù)據(jù)類型當(dāng)成對(duì)象操作,Java為每一個(gè)基本數(shù)據(jù)類型都引入了對(duì)應(yīng)的包裝類型(wrapper class),int的包裝類就是Integer,從Java 5開始引入了自動(dòng)裝箱/拆箱機(jī)制,使得二者可以相互轉(zhuǎn)換。

Java 為每個(gè)原始類型提供了包裝類型:

原始類型: boolean,char,byte,short,int,long,float,double
包裝類型:Boolean,Character,Byte,Short,Integer,Long,F(xiàn)loat,Double

5、&和&&的區(qū)別?

&運(yùn)算符有兩種用法:(1)按位與;(2)邏輯與。&&運(yùn)算符是短路與運(yùn)算。邏輯與跟短路與的差別是非常巨大的,雖然二者都要求運(yùn)算符左右兩端的布爾值都是true整個(gè)表達(dá)式的值才是true。&&之所以稱為短路運(yùn)算是因?yàn),如?amp;&左邊的表達(dá)式的值是false,右邊的表達(dá)式會(huì)被直接短路掉,不會(huì)進(jìn)行運(yùn)算。很多時(shí)候我們可能都需要用&&而不是&,例如在驗(yàn)證用戶登錄時(shí)判定用戶名不是null而且不是空字符串,應(yīng)當(dāng)寫為:username != null &&!username.equals(“”),二者的順序不能交換,更不能用&運(yùn)算符,因?yàn)榈谝粋(gè)條件如果不成立,根本不能進(jìn)行字符串的equals比較,否則會(huì)產(chǎn)生NullPointerException異常。注意:邏輯或運(yùn)算符(|)和短路或運(yùn)算符(||)的差別也是如此。

6、Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在參數(shù)上加0.5然后進(jìn)行下取整。

7、switch 是否能作用在byte 上,是否能作用在long,float 上,是否能作用在String上?

在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。從Java 5開始,Java中引入了枚舉類型,expr也可以是enum類型,從Java 7開始,expr還可以是字符串(String),但是長(zhǎng)整型(long),浮點(diǎn)數(shù)(float)在目前所有的版本中都是不可以的。

8、兩個(gè)對(duì)象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對(duì)不對(duì)?

不對(duì),如果兩個(gè)對(duì)象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應(yīng)當(dāng)相同。

Java對(duì)于eqauls方法和hashCode方法是這樣規(guī)定的:

(1)如果兩個(gè)對(duì)象相同(equals方法返回true),那么它們的hashCode值一定要相同;
(2)如果兩個(gè)對(duì)象的hashCode相同,它們并不一定相同。當(dāng)然,你未必要按照要求去做,但是如果你違背了上述原則就會(huì)發(fā)現(xiàn)在使用容器時(shí),相同的對(duì)象可以出現(xiàn)在Set集合中,同時(shí)增加新元素的效率會(huì)大大下降(對(duì)于使用哈希存儲(chǔ)的系統(tǒng),如果哈希碼頻繁的沖突將會(huì)造成存取性能急劇下降)。

補(bǔ)充:關(guān)于equals和hashCode方法,很多Java程序都知道,但很多人也就是僅僅知道而已,在Joshua Bloch的大作《Effective Java》(很多軟件公司,《Effective Java》、《Java編程思想》以及《重構(gòu):改善既有代碼質(zhì)量》是Java程序員必看書籍,如果你還沒看過,那就趕緊去亞馬遜買一本吧)中是這樣介紹equals方法的:首先equals方法必須滿足自反性(x.equals(x)必須返回true)、對(duì)稱性(x.equals(y)返回true時(shí),y.equals(x)也必須返回true)、傳遞性(x.equals(y)和y.equals(z)都返回true時(shí),x.equals(z)也必須返回true)和一致性(當(dāng)x和y引用的對(duì)象信息沒有被修改時(shí),多次調(diào)用x.equals(y)應(yīng)該得到同樣的返回值),而且對(duì)于任何非null值的引用x,x.equals(null)必須返回false。

實(shí)現(xiàn)高質(zhì)量的equals方法的訣竅包括:

使用==操作符檢查”參數(shù)是否為這個(gè)對(duì)象的引用”;
使用instanceof操作符檢查”參數(shù)是否為正確的類型”;
對(duì)于類中的關(guān)鍵屬性,檢查參數(shù)傳入對(duì)象的屬性是否與之相匹配;
編寫完equals方法后,問自己它是否滿足對(duì)稱性、傳遞性、一致性;
重寫equals時(shí)總是要重寫hashCode;
不要將equals方法參數(shù)中的Object對(duì)象替換為其他的類型,在重寫時(shí)不要忘掉@Override注解。

9、當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì)象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引用傳遞?

是值傳遞。Java語(yǔ)言的方法調(diào)用只支持參數(shù)的值傳遞。當(dāng)一個(gè)對(duì)象實(shí)例作為一個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是對(duì)該對(duì)象的引用。對(duì)象的屬性可以在被調(diào)用過程中被改變,但對(duì)對(duì)象引用的改變是不會(huì)影響到調(diào)用者的。C++和C#中可以通過傳引用或傳輸出參數(shù)來(lái)改變傳入的參數(shù)的值。

10、String和StringBuilder、StringBuffer的區(qū)別?

Java平臺(tái)提供了兩種類型的字符串:String和StringBuffer/StringBuilder,它們可以儲(chǔ)存和操作字符串。其中String是只讀字符串,也就意味著String引用的字符串內(nèi)容是不能被改變的。而StringBuffer/StringBuilder類表示的字符串對(duì)象可以直接進(jìn)行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,區(qū)別在于它是在單線程環(huán)境下使用的,因?yàn)樗乃蟹矫娑紱]有被synchronized修飾,因此它的效率也比StringBuffer要高。

11、抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native),是否可同時(shí)被synchronized修飾?

都不能。抽象方法需要子類重寫,而靜態(tài)的方法是無(wú)法被重寫的,因此二者是矛盾的。本地方法是由本地代碼(如C代碼)實(shí)現(xiàn)的方法,而抽象方法是沒有實(shí)現(xiàn)的,也是矛盾的。synchronized和方法的實(shí)現(xiàn)細(xì)節(jié)有關(guān),抽象方法不涉及實(shí)現(xiàn)細(xì)節(jié),因此也是相互矛盾的。

12、闡述靜態(tài)變量和實(shí)例變量的區(qū)別。

靜態(tài)變量是被static修飾符修飾的變量,也稱為類變量,它屬于類,不屬于類的任何一個(gè)對(duì)象,一個(gè)類不管創(chuàng)建多少個(gè)對(duì)象,靜態(tài)變量在內(nèi)存中有且僅有一個(gè)拷貝;實(shí)例變量必須依存于某一實(shí)例,需要先創(chuàng)建對(duì)象然后通過對(duì)象才能訪問到它。靜態(tài)變量可以實(shí)現(xiàn)讓多個(gè)對(duì)象共享內(nèi)存。

補(bǔ)充:在Java開發(fā)中,上下文類和工具類中通常會(huì)有大量的靜態(tài)成員。

13、Object中有哪些公共方法?
equals()
clone()
getClass()
notify(),notifyAll(),wait()
toString()

14、是否可以從一個(gè)靜態(tài)(static)方法內(nèi)部發(fā)出對(duì)非靜態(tài)(non-static)方法的調(diào)用?

不可以,靜態(tài)方法只能訪問靜態(tài)成員,因?yàn)榉庆o態(tài)方法的調(diào)用要先創(chuàng)建對(duì)象,在調(diào)用靜態(tài)方法時(shí)可能對(duì)象并沒有被初始化。

15、深拷貝和淺拷貝的區(qū)別是什么?

淺拷貝:被復(fù)制對(duì)象的所有變量都含有與原來(lái)的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用仍然指向原來(lái)的對(duì)象。換言之,淺拷貝僅僅復(fù)制所考慮的對(duì)象,而不復(fù)制它所引用的對(duì)象。

深拷貝:被復(fù)制對(duì)象的所有變量都含有與原來(lái)的對(duì)象相同的值,而那些引用其他對(duì)象的變量將指向被復(fù)制過的新對(duì)象,而不再是原有的那些被引用的對(duì)象。換言之,深拷貝把要復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。

16、如何實(shí)現(xiàn)對(duì)象克隆?

有兩種方式:
1、實(shí)現(xiàn)Cloneable接口并重寫Object類中的clone()方法;
2、實(shí)現(xiàn)Serializable接口,通過對(duì)象的序列化和反序列化實(shí)現(xiàn)克隆,可以實(shí)現(xiàn)真正的深度克隆。

17、String s = new String(“xyz”);創(chuàng)建了幾個(gè)字符串對(duì)象?

兩個(gè)對(duì)象,一個(gè)是靜態(tài)區(qū)的”xyz”,一個(gè)是用new創(chuàng)建在堆上的對(duì)象。

18、java中==和eqauls()的區(qū)別,equals()和`hashcode的區(qū)別

==是運(yùn)算符,用于比較兩個(gè)變量是否相等,而equals是Object類的方法,用于比較兩個(gè)對(duì)象是否相等.默認(rèn)Object類的equals方法是比較兩個(gè)對(duì)象的地址,此時(shí)和==的結(jié)果一樣.換句話說(shuō):基本類型比較用==,比較的是他們的值.默認(rèn)下,對(duì)象用==比較時(shí),比較的是內(nèi)存地址,如果需要比較對(duì)象內(nèi)容,需要重寫equal方法。

19、a==b與a.equals(b)有什么區(qū)別

如果a 和b 都是對(duì)象,則 a==b 是比較兩個(gè)對(duì)象的引用,只有當(dāng) a 和 b 指向的是堆中的同一個(gè)對(duì)象才會(huì)返回 true,而 a.equals(b) 是進(jìn)行邏輯比較,所以通常需要重寫該方法來(lái)提供邏輯一致性的比較。例如,String 類重寫 equals() 方法,所以可以用于兩個(gè)不同對(duì)象,但是包含的字母相同的比較。

20、接口是否可繼承(extends)接口?抽象類是否可實(shí)現(xiàn)(implements)接口?抽象類是否可繼承具體類(concrete class)?

接口可以繼承接口,而且支持多重繼承。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類可繼承具體類也可以繼承抽象類。

21、Java 中的final關(guān)鍵字有哪些用法?

(1)修飾類:表示該類不能被繼承;
(2)修飾方法:表示方法不能被重寫;
(3)修飾變量:表示變量只能一次賦值以后值不能被修改(常量)。

22、throw和throws的區(qū)別

throw用于主動(dòng)拋出java.lang.Throwable 類的一個(gè)實(shí)例化對(duì)象,意思是說(shuō)你可以通過關(guān)鍵字 throw 拋出一個(gè) Error 或者 一個(gè)Exception,如:throw new IllegalArgumentException(“size must be multiple of 2″)。

throws 的作用是作為方法聲明和簽名的一部分,方法被拋出相應(yīng)的異常以便調(diào)用者能處理。Java 中,任何未處理的受檢查異常強(qiáng)制在 throws 子句中聲明。

23、Error和Exception有什么區(qū)別?

Error表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,是恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問題;比如內(nèi)存溢出,不可能指望程序能處理這樣的情況;
Exception表示需要捕捉或者需要程序進(jìn)行處理的異常,是一種設(shè)計(jì)或?qū)崿F(xiàn)問題;也就是說(shuō),它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況。

24、Java語(yǔ)言如何進(jìn)行異常處理,關(guān)鍵字:throws、throw、try、catch、finally分別如何使用?

Java通過面向?qū)ο蟮姆椒ㄟM(jìn)行異常處理,把各種不同的異常進(jìn)行分類,并提供了良好的接口。在Java中,每個(gè)異常都是一個(gè)對(duì)象,它是Throwable類或其子類的實(shí)例。當(dāng)一個(gè)方法出現(xiàn)異常后便拋出一個(gè)異常對(duì)象,該對(duì)象中包含有異常信息,調(diào)用這個(gè)對(duì)象的方法可以捕獲到這個(gè)異常并可以對(duì)其進(jìn)行處理。

Java的異常處理是通過5個(gè)關(guān)鍵詞來(lái)實(shí)現(xiàn)的:try、catch、throw、throws和finally。

一般情況下是用try來(lái)執(zhí)行一段程序,如果系統(tǒng)會(huì)拋出(throw)一個(gè)異常對(duì)象,可以通過它的類型來(lái)捕獲(catch)它,或通過總是執(zhí)行代碼塊(finally)來(lái)處理; try用來(lái)指定一塊預(yù)防所有異常的程序; catch子句緊跟在try塊后面,用來(lái)指定你想要捕獲的異常的類型; throw語(yǔ)句用來(lái)明確地拋出一個(gè)異常; throws用來(lái)聲明一個(gè)方法可能拋出的各種異常(當(dāng)然聲明異常時(shí)允許無(wú)病呻吟); finally為確保一段代碼不管發(fā)生什么異常狀況都要被執(zhí)行;

try語(yǔ)句可以嵌套,每當(dāng)遇到一個(gè)try語(yǔ)句,異常的結(jié)構(gòu)就會(huì)被放入異常棧中,直到所有的try語(yǔ)句都完成。如果下一級(jí)的try語(yǔ)句沒有對(duì)某種異常進(jìn)行處理,異常棧就會(huì)執(zhí)行出棧操作,直到遇到有處理這種異常的try語(yǔ)句或者最終將異常拋給JVM。

25、運(yùn)行時(shí)異常與受檢異常有何異同?

異常表示程序運(yùn)行過程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見運(yùn)行錯(cuò)誤,只要程序設(shè)計(jì)得沒有問題通常就不會(huì)發(fā)生。受檢異常跟程序運(yùn)行的上下文環(huán)境有關(guān),即使程序設(shè)計(jì)無(wú)誤,仍然可能因使用的問題而引發(fā)。Java編譯器要求方法必須聲明拋出可能發(fā)生的受檢異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。

異常和繼承一樣,是面向?qū)ο蟪绦蛟O(shè)計(jì)中經(jīng)常被濫用的東西,在Effective Java中對(duì)異常的使用給出了以下指導(dǎo)原則:

不要將異常處理用于正常的控制流(設(shè)計(jì)良好的API不應(yīng)該強(qiáng)迫它的調(diào)用者為了正常的控制流而使用異常)
對(duì)可以恢復(fù)的情況使用受檢異常,對(duì)編程錯(cuò)誤使用運(yùn)行時(shí)異常
避免不必要的使用受檢異常(可以通過一些狀態(tài)檢測(cè)手段來(lái)避免異常的發(fā)生)
優(yōu)先使用標(biāo)準(zhǔn)的異常
每個(gè)方法拋出的異常都要有文檔
保持異常的原子性
不要在catch中忽略掉捕獲到的異常

26、列出一些你常見的運(yùn)行時(shí)異常?

ArithmeticException(算術(shù)異常)
ClassCastException (類轉(zhuǎn)換異常)
IllegalArgumentException (非法參數(shù)異常)
IndexOutOfBoundsException (下標(biāo)越界異常)
NullPointerException (空指針異常)
SecurityException (安全異常)

27、闡述final、finally、finalize的區(qū)別

final:修飾符(關(guān)鍵字)有三種用法:如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,即不能被繼承,因此它和abstract是反義詞。將變量聲明為final,可以保證它們?cè)谑褂弥胁槐桓淖儯宦暶鳛閒inal的變量必須在聲明時(shí)給定初值,而在以后的引用中只能讀取不可修改。被聲明為final的方法也同樣只能使用,不能在子類中被重寫。

finally:通常放在try…catch…的后面構(gòu)造總是執(zhí)行代碼塊,這就意味著程序無(wú)論正常執(zhí)行還是發(fā)生異常,這里的代碼只要JVM不關(guān)閉都能執(zhí)行,可以將釋放外部資源的代碼寫在finally塊中。

finalize:Object類中定義的方法,Java中允許使用finalize()方法在垃圾收集器將對(duì)象從內(nèi)存中清除出去之前做必要的清理工作。這個(gè)方法是由垃圾收集器在銷毀對(duì)象時(shí)調(diào)用的,通過重寫finalize()方法可以整理系統(tǒng)資源或者執(zhí)行其他清理工作。

28、java當(dāng)中的四種引用

強(qiáng)引用,軟引用,弱引用,虛引用.不同的引用類型主要體現(xiàn)在GC上:

強(qiáng)引用:如果一個(gè)對(duì)象具有強(qiáng)引用,它就不會(huì)被垃圾回收器回收。即使當(dāng)前內(nèi)存空間不足,JVM也不會(huì)回收它,而是拋出 OutOfMemoryError 錯(cuò)誤,使程序異常終止。如果想中斷強(qiáng)引用和某個(gè)對(duì)象之間的關(guān)聯(lián),可以顯式地將引用賦值為null,這樣一來(lái)的話,JVM在合適的時(shí)間就會(huì)回收該對(duì)象

軟引用:在使用軟引用時(shí),如果內(nèi)存的空間足夠,軟引用就能繼續(xù)被使用,而不會(huì)被垃圾回收器回收,只有在內(nèi)存不足時(shí),軟引用才會(huì)被垃圾回收器回收。

弱引用:具有弱引用的對(duì)象擁有的生命周期更短暫。因?yàn)楫?dāng) JVM 進(jìn)行垃圾回收,一旦發(fā)現(xiàn)弱引用對(duì)象,無(wú)論當(dāng)前內(nèi)存空間是否充足,都會(huì)將弱引用回收。不過由于垃圾回收器是一個(gè)優(yōu)先級(jí)較低的線程,所以并不一定能迅速發(fā)現(xiàn)弱引用對(duì)象

虛引用:顧名思義,就是形同虛設(shè),如果一個(gè)對(duì)象僅持有虛引用,那么它相當(dāng)于沒有引用,在任何時(shí)候都可能被垃圾回收器回收。

29、為什么要有不同的引用類型

不像C語(yǔ)言,我們可以控制內(nèi)存的申請(qǐng)和釋放,在Java中有時(shí)候我們需要適當(dāng)?shù)目刂茖?duì)象被回收的時(shí)機(jī),因此就誕生了不同的引用類型,可以說(shuō)不同的引用類型實(shí)則是對(duì)GC回收時(shí)機(jī)不可控的妥協(xié).有以下幾個(gè)使用場(chǎng)景可以充分的說(shuō)明:

利用軟引用和弱引用解決OOM問題:用一個(gè)HashMap來(lái)保存圖片的路徑和相應(yīng)圖片對(duì)象關(guān)聯(lián)的軟引用之間的映射關(guān)系,在內(nèi)存不足時(shí),JVM會(huì)自動(dòng)回收這些緩存圖片對(duì)象所占用的空間,從而有效地避免了OOM的問題.
通過軟引用實(shí)現(xiàn)Java對(duì)象的高速緩存:比如我們創(chuàng)建了一Person的類,如果每次需要查詢一個(gè)人的信息,哪怕是幾秒中之前剛剛查詢過的,都要重新構(gòu)建一個(gè)實(shí)例,這將引起大量Person對(duì)象的消耗,并且由于這些對(duì)象的生命周期相對(duì)較短,會(huì)引起多次GC影響性能。此時(shí),通過軟引用和 HashMap 的結(jié)合可以構(gòu)建高速緩存,提供性能.

30、內(nèi)部類的作用

內(nèi)部類可以有多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其他外圍對(duì)象的信息相互獨(dú)立.在單個(gè)外圍類當(dāng)中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一接口,或者繼承同一個(gè)類.創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻不依賴于外部類對(duì)象的創(chuàng)建.內(nèi)部類并沒有令人疑惑的”is-a”關(guān)系,它就像是一個(gè)獨(dú)立的實(shí)體.
內(nèi)部類提供了更好的封裝,除了該外圍類,其他類都不能訪問

31、SimpleDateFormat是線程安全的嗎?

非常不幸,DateFormat 的所有實(shí)現(xiàn),包括 SimpleDateFormat 都不是線程安全的,因此你不應(yīng)該在多線程序中使用,除非是在對(duì)外線程安全的環(huán)境中使用,如 將 SimpleDateFormat 限制在 ThreadLocal 中。如果你不這么做,在解析或者格式化日期的時(shí)候,可能會(huì)獲取到一個(gè)不正確的結(jié)果。因此,從日期、時(shí)間處理的所有實(shí)踐來(lái)說(shuō),我強(qiáng)力推薦 joda-time 庫(kù)。

32、如何格式化日期?

Java 中,可以使用 SimpleDateFormat 類或者 joda-time 庫(kù)來(lái)格式日期。DateFormat 類允許你使用多種流行的格式來(lái)格式化日期。參見答案中的示例代碼,代碼中演示了將日期格式化成不同的格式,如 dd-MM-yyyy 或 ddMMyyyy。

33、說(shuō)出幾條 Java 中方法重載的最佳實(shí)踐?

下面有幾條可以遵循的方法重載的最佳實(shí)踐來(lái)避免造成自動(dòng)裝箱的混亂。
不要重載這樣的方法:一個(gè)方法接收 int 參數(shù),而另個(gè)方法接收 Integer 參數(shù)。
不要重載參數(shù)數(shù)量一致,而只是參數(shù)順序不同的方法。
如果重載的方法參數(shù)個(gè)數(shù)多于 5 個(gè),采用可變參數(shù)。

34、說(shuō)說(shuō)反射的用途及實(shí)現(xiàn)

反射機(jī)制是Java語(yǔ)言中一個(gè)非常重要的特性,它允許程序在運(yùn)行時(shí)進(jìn)行自我檢查,同時(shí)也允許對(duì)其內(nèi)部成員進(jìn)行操作。

反射機(jī)制提供的功能主要有:得到一個(gè)對(duì)象所屬的類;獲取一個(gè)類的所有成員變量和方法;在運(yùn)行時(shí)創(chuàng)建對(duì)象;在運(yùn)行時(shí)調(diào)用對(duì)象的方法;

35、說(shuō)說(shuō)自定義注解的場(chǎng)景及實(shí)現(xiàn)

登陸、權(quán)限攔截、日志處理,以及各種 Java 框架,如 Spring,Hibernate,JUnit 提到注解就不能不說(shuō)反射,Java 自定義注解是通過運(yùn)行時(shí)靠反射獲取注解。

實(shí)際開發(fā)中,例如我們要獲取某個(gè)方法的調(diào)用日志,可以通過 AOP(動(dòng)態(tài)代理機(jī)制)給方法添加切面,通過反射來(lái)獲取方法包含的注解,如果包含日志注解,就進(jìn)行日志記錄。 反射的實(shí)現(xiàn)在 Java 應(yīng)用層面上講,是通過對(duì) Class 對(duì)象的操作實(shí)現(xiàn)的,Class 對(duì)象為我們提供了一系列方法對(duì)類進(jìn)行操作。在 JVM 這個(gè)角度來(lái)說(shuō),Class 文件是一組以 8 位字節(jié)為基礎(chǔ)單位的二進(jìn)制流,各個(gè)數(shù)據(jù)項(xiàng)目按嚴(yán)格的順序緊湊的排列在 Class 文件中,里面包含了類、方法、字段等等相關(guān)數(shù)據(jù)。

通過對(duì) Class 數(shù)據(jù)流的處理我們即可得到字段、方法等數(shù)據(jù)。
反對(duì)
回帖2
  • 人贊過
  • 人反對(duì)
查看更多
查看更多
相關(guān)推薦
回復(fù)(2)
V17 發(fā)表于2019-10-23 19:13:45

感謝分享
反對(duì)

快速回帖 使用(可批量傳圖、插入視頻等)

表情
新用戶注冊(cè)
  Ctrl + Enter 快速發(fā)布
 

 19