自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

吊打面試官系列:說(shuō)說(shuō)反射的用途及實(shí)現(xiàn)?

開(kāi)發(fā) 后端
反射是Java程序開(kāi)發(fā)語(yǔ)言的特征之一,它允許動(dòng)態(tài)地發(fā)現(xiàn)和綁定類(lèi)、方法、字段,以及所有其他的由于有所產(chǎn)生的的元素。通過(guò)反射,能夠在需要時(shí)完成創(chuàng)建實(shí)例、調(diào)用方法和訪問(wèn)字段的工作。

 

反射是什么?

 

反射是Java程序開(kāi)發(fā)語(yǔ)言的特征之一,它允許動(dòng)態(tài)地發(fā)現(xiàn)和綁定類(lèi)、方法、字段,以及所有其他的由于有所產(chǎn)生的的元素。通過(guò)反射,能夠在需要時(shí)完成創(chuàng)建實(shí)例、調(diào)用方法和訪問(wèn)字段的工作。

反射機(jī)制主要提供功能

 

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi)
  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類(lèi)的對(duì)象
  • 在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法
  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法,通過(guò)反射甚至可以調(diào)用到private修飾的方法
  • 生成動(dòng)態(tài)代理

反射在牛逼框架中的使用

 

  • Spring 框架的 IOC 基于反射創(chuàng)建對(duì)象和設(shè)置依賴(lài)屬性。
  • Spring MVC 的請(qǐng)求調(diào)用對(duì)應(yīng)方法,也是通過(guò)反射。
  • JDBC 的 Class#forName(String className) 方法,也是使用反射。

反射中,Class.forName 和 ClassLoader 區(qū)別?

 

這兩者,都可用來(lái)對(duì)類(lèi)進(jìn)行加載。差別在于:

  • Class#forName(…) 方法,除了將類(lèi)的 .class 文件加載到JVM 中之外,還會(huì)對(duì)類(lèi)進(jìn)行解釋?zhuān)瑘?zhí)行類(lèi)中的 static 塊。
  • ClassLoader 只干一件事情,就是將 .class 文件加載到 JVM 中,不會(huì)執(zhí)行 static 中的內(nèi)容,只有在 newInstance 才會(huì)去執(zhí)行 static 塊。

反射的常用類(lèi)

 

Java中反射相關(guān)的類(lèi)大部分都在rt.jar下java.lang.reflect中,其實(shí)需要的類(lèi)并不多,主要有以下幾個(gè):

  1. java.lang.Class 

Class類(lèi)的實(shí)例表示正在運(yùn)行的Java類(lèi)和接口。

  1. java.lang.reflect.Field 

提供有關(guān)類(lèi)或者接口的屬性信息,以及對(duì)它的動(dòng)態(tài)訪問(wèn)權(quán)限。反射的字段可能是一個(gè)類(lèi)(靜態(tài))屬性或?qū)嵗龑傩裕?jiǎn)單的理解可以把它看成一個(gè)封裝反射類(lèi)的屬性的類(lèi)。有點(diǎn)繞,慢慢體會(huì)吧。

  1. java.lang.reflect.Constructor 

提供關(guān)于類(lèi)的單個(gè)構(gòu)造方法的信息以及對(duì)它的訪問(wèn)權(quán)限。這個(gè)類(lèi)和Field類(lèi)不同,F(xiàn)iled類(lèi)封裝類(lèi)反射類(lèi)的屬性,而Constructor類(lèi)則封裝類(lèi)反射類(lèi)的構(gòu)造方法。

  1. java.lang.reflect.Method 

提供關(guān)于類(lèi)和接口上單個(gè)方法的信息。所反映的方法可能是類(lèi)方法或者實(shí)例方法(包括抽象方法)。這個(gè)類(lèi)不難理解,他的作用就是用來(lái)封裝反射類(lèi)方法的一個(gè)類(lèi)。

  1. java.lang.reflect.Modifier 

提供了用于解碼類(lèi)和成員訪問(wèn)修飾符的靜態(tài)方法和常量。修飾符集合被表示為具有表示不同修飾符的不同位位置的整數(shù)。

  1. java.lang.reflect.Array 

提供了動(dòng)態(tài)創(chuàng)解決數(shù)組和訪問(wèn)數(shù)組的靜態(tài)方法,該類(lèi)中的所有方法都是靜態(tài)方法。

反射的優(yōu)缺點(diǎn)

 

優(yōu)點(diǎn)

  • 可以在程序運(yùn)行的過(guò)程中,操作這些對(duì)象。
  • 可以解耦,提高程序的可擴(kuò)展性。

缺點(diǎn)

  • 因?yàn)槭荍VM操作,所以對(duì)于性能來(lái)說(shuō)會(huì)有所下降。
  • 容易對(duì)程序源碼造成一定的混亂。

探索 Class

 

java文件編譯后變成class文件,class文件被類(lèi)加載器加載到內(nèi)存中,并且JVM根據(jù)其字節(jié)數(shù)組創(chuàng)建了對(duì)應(yīng)的Class對(duì)象。

Class類(lèi)是Java反射的起源,針對(duì)任何一個(gè)我們想使用的類(lèi),只有先為它產(chǎn)生一個(gè)Class對(duì)象,接下來(lái)就可以通過(guò)Class對(duì)象獲取其他的信息。

JVM為每個(gè)類(lèi)管理著一個(gè)獨(dú)一無(wú)二的Class對(duì)象,當(dāng)我們需要?jiǎng)?chuàng)建每個(gè)類(lèi)的對(duì)象時(shí),JVM會(huì)檢查所要加載的類(lèi)對(duì)應(yīng)的Class對(duì)象是否已經(jīng)存在。不存在,則JVM會(huì)根據(jù)類(lèi)加載機(jī)制加載并創(chuàng)建對(duì)應(yīng)的Class對(duì)象,最后使用Class對(duì)象創(chuàng)建出我們通常使用的實(shí)例對(duì)象。

獲取Class類(lèi)的三種方式

1.調(diào)用Object類(lèi)的getClass()方法獲得Class對(duì)象。

2.使用Class類(lèi)的forName("com.tian.XXX")靜態(tài)方法獲取與字符串對(duì)應(yīng)的對(duì)象(類(lèi)或接口的全限定名)。

3.使用.class獲取該類(lèi)性的Class對(duì)象。

Class常用方法

 

方法非常之多。

獲取類(lèi)信息

了解了Java反射的詳細(xì)細(xì)節(jié)之后,我們可以使用反射機(jī)制來(lái)獲取類(lèi)中的信息。

 

創(chuàng)建對(duì)象

使用無(wú)參構(gòu)造方法創(chuàng)建對(duì)象

比如說(shuō)下面這段代碼:

  1. Class clazz = Class.forName("java.lang.String"); 
  2. String str = (String)clazz.newInstance(); 

這里需要注意,這個(gè)類(lèi)必須是有無(wú)參構(gòu)造方法,不然這種方式會(huì)報(bào)錯(cuò)的。

使用有參構(gòu)造方法

可以使用三個(gè)步驟來(lái)完成:

1.獲取指定類(lèi)對(duì)應(yīng)的Class對(duì)象

2.通過(guò)Class對(duì)象獲取滿(mǎn)足指定參數(shù)類(lèi)型要求的構(gòu)造方法類(lèi)對(duì)象

3.調(diào)用指定的Constructor對(duì)應(yīng)的newInstance方法,傳入對(duì)應(yīng)的參數(shù)值,創(chuàng)建出我們想要的實(shí)例對(duì)象。

  1. Class clazz = Class.forName("java.lang.String"); 
  2. Constructor constructor = clas.getConstructor(String.class); 
  3. String str = (String)constructor.newInstance("hello world"); 

這樣就創(chuàng)建了一個(gè)String對(duì)象實(shí)例。

調(diào)用方法

前面已經(jīng)聊過(guò)Method這個(gè)類(lèi),我們可以通過(guò)Method類(lèi)中的invoke方法動(dòng)態(tài)調(diào)用器方法。

  1. public final class Method extends Executable { 
  2.     public Object invoke(Object obj, Object... args){ 
  3.     //.... 
  4.     } 

這個(gè)方法的第一個(gè)參數(shù)是一個(gè)對(duì)象類(lèi)型,表示要在指定的這個(gè)對(duì)象上調(diào)用這個(gè)方法(方法名稱(chēng))。第二個(gè)參數(shù)是可變參數(shù),用來(lái)給這個(gè)方法傳遞參數(shù)值;

invoke方法里返回的值用來(lái)表示動(dòng)態(tài)調(diào)用指定方法后的返回值。如果調(diào)用私有的方法,先調(diào)用setAccessible(true)來(lái)曲線(xiàn)Java語(yǔ)言堆笨方法的訪問(wèn)檢查,然后再調(diào)用invoke方法來(lái)真正執(zhí)行這個(gè)私有方法。

訪問(wèn)成員變量的值

使用反射可以獲取類(lèi)的成員變量的對(duì)象代表,成員變量的對(duì)象代表是

java.lang.reflect.Field類(lèi)的實(shí)例,可以使用他的getXyy()方法來(lái)獲取指定對(duì)象上的值,也可以使用setXyy()方法來(lái)動(dòng)態(tài)修改指定對(duì)象上的值,其中xyy是成員變量。

比如說(shuō):setAge(22);其中age就是成員變量。

操作數(shù)組

數(shù)組也是一個(gè)度一項(xiàng),可以通過(guò)反射來(lái)查看數(shù)組的各個(gè)屬性的信息,比如

  1. ingt [] intArr=new Int[10]; 
  2. Sysytem.out.prinlt("數(shù)組類(lèi)型:"+intArr.getClass.getComponentType().getName()); 
  3.  
  4. Object obj=Array.newInstance(int.class, 10); 
  5. //維數(shù)組賦值 
  6. for(int i=0;i<10;i++){ 
  7.     Array.setInt(obj,i,i); 
  8. for(int i = 0;i<10;i++){ 
  9.     System.out.print("第"+i+"好元素為"+Array.getInt(obj,i)); 

反射與動(dòng)態(tài)代理

代理模式是Java中使用頻率相當(dāng)高的設(shè)計(jì)模式之一,尤其是在牛逼的框架中,Spring,Mybatis,Dubbo等框架中。

其中反射就是一個(gè)很好的應(yīng)用。

靜態(tài)代理模式我們就沒(méi)有必要提他了,相當(dāng)于一個(gè)業(yè)務(wù)需要代理,你就得給他搞一個(gè)代理類(lèi)。全是手動(dòng)搞出來(lái)的。

動(dòng)態(tài)代理的原理就是,在程序運(yùn)行時(shí)候根據(jù)需要?jiǎng)討B(tài)地創(chuàng)建目標(biāo)類(lèi)的代理對(duì)象,典型應(yīng)用場(chǎng)景:

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

關(guān)于動(dòng)態(tài)代理,后面有專(zhuān)門(mén)的文章分析。

到此我們的反射相關(guān)的意見(jiàn)講完了。具體還是建議自己下去手動(dòng)敲敲代碼,體會(huì)一下,便于更深刻的理解。

總結(jié)

 

面試被問(wèn)到,建議回答以下幾個(gè)方面的內(nèi)容:

1.反射是什么

2.提供了什么功能

3.常用類(lèi)有哪些

4.優(yōu)缺點(diǎn)是什么

5.其他框架中國(guó)的應(yīng)用(動(dòng)態(tài)代理)

本文轉(zhuǎn)載自微信公眾號(hào)「Java后端技術(shù)全棧」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java后端技術(shù)全棧公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: Java后端技術(shù)全棧
相關(guān)推薦

2024-03-14 14:56:22

反射Java數(shù)據(jù)庫(kù)連接

2024-08-22 10:39:50

@Async注解代理

2024-03-05 10:33:39

AOPSpring編程

2025-04-08 00:00:00

@AsyncSpring異步

2024-07-31 08:28:37

DMAIOMMap

2024-12-06 07:00:00

2024-09-20 08:36:43

零拷貝數(shù)據(jù)傳輸DMA

2024-03-22 06:56:24

零拷貝技術(shù)數(shù)據(jù)傳輸數(shù)據(jù)拷貝

2024-02-29 16:49:20

volatileJava并發(fā)編程

2024-08-29 16:30:27

2024-08-12 17:36:54

2021-06-07 17:12:22

線(xiàn)程安全Atomic

2024-06-04 09:02:03

2025-02-28 00:00:00

2024-03-01 11:33:31

2024-12-04 14:45:14

零拷貝技術(shù)CPU 拷貝Zero-copy

2024-03-28 10:37:44

IoC依賴(lài)注入依賴(lài)查找

2021-05-20 08:34:03

CDN原理網(wǎng)絡(luò)

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級(jí)別幻讀
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)