哪些類用來實(shí)現(xiàn)java反射機(jī)制 java反射常用的類有哪些
夕逆IT
- 前端設(shè)計(jì)
- 2023-08-13
- 112

老鐵們,大家好,相信還有很多朋友對(duì)于哪些類用來實(shí)現(xiàn)java反射機(jī)制和java反射常用的類有哪些的相關(guān)問題不太懂,沒關(guān)系,今天就由我來為大家分享分享哪些類用來實(shí)現(xiàn)java...
老鐵們,大家好,相信還有很多朋友對(duì)于哪些類用來實(shí)現(xiàn)java反射機(jī)制和java反射常用的類有哪些的相關(guān)問題不太懂,沒關(guān)系,今天就由我來為大家分享分享哪些類用來實(shí)現(xiàn)java反射機(jī)制以及java反射常用的類有哪些的問題,文章篇幅可能偏長(zhǎng),希望可以幫助到大家,下面一起來看看吧!
語言反射意義
反射就是自我感知,自我控制。說白了就是編程語言可以獲取到自身的一些對(duì)象,對(duì)象的屬性和方法。面向?qū)ο笙到y(tǒng)比較容易支持反射,比如JAVA。但是反射有兩個(gè)問題,①是性能比較差。②是可讀性差,IDE支持也差。所以盡量少用反射,最好別用。
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制。
Java能反射實(shí)現(xiàn),內(nèi)部接口和內(nèi)部抽象類作為參數(shù)的方法嗎
題目不是很明確,但是Java反射能得到內(nèi)部類和內(nèi)部接口,同樣肯定也可以傳入作為參數(shù)。代碼如下:
一個(gè)類,有內(nèi)部類和接口。
測(cè)試類:可以得到普通屬性和方法,內(nèi)部類和接口,并且可以給內(nèi)部類初始化。接口不能被實(shí)例化。但是可以被外部類實(shí)現(xiàn),再實(shí)例化。
得到的測(cè)試結(jié)果是:
C++需要反射嗎
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取的以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制
.Java
反射機(jī)制主要提供了以下功能:在運(yùn)行時(shí)判定任意一個(gè)對(duì)象所屬的類;在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;在運(yùn)行時(shí)判定任意一個(gè)類所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;生成動(dòng)態(tài)代理.誰能給我講一講Java中反射機(jī)制
在學(xué)習(xí)Java反射之前,先讓我們看看這幾個(gè)概念。
01.解釋型語言和編譯型語言解釋型語言:不需要編譯,在運(yùn)行的時(shí)候逐行翻譯解釋;修改代碼時(shí)可以直接修改,可以快速部署,不過性能上會(huì)比編譯型語言稍差;比如JavaScript、Python;
編譯型語言:需要通過編譯器將源代碼編譯成機(jī)器碼才能執(zhí)行;編譯之后如果需要修改代碼,在執(zhí)行之前就需要重新編譯。比如C語言;
Java嚴(yán)格來說也是編譯型語言,但又介于編譯型和解釋型之間;Java不直接生成機(jī)器碼而是生成中間碼:編譯期間,是將源碼交給編譯器生成class文件(字節(jié)碼),這個(gè)過程中只做了翻譯的工作,并沒有把代碼放入內(nèi)存運(yùn)行;當(dāng)進(jìn)入運(yùn)行期,字節(jié)碼才被Java虛擬機(jī)加載、解釋成機(jī)器語言并運(yùn)行。
02.動(dòng)態(tài)語言和靜態(tài)語言動(dòng)態(tài)語言:是指程序在運(yùn)行時(shí)可以改變自身結(jié)構(gòu),在運(yùn)行時(shí)確定數(shù)據(jù)類型,一個(gè)對(duì)象是否能執(zhí)行某操作,只取決于它有沒有對(duì)應(yīng)的方法,而不在乎它是否是某種類型的對(duì)象;比如JavaScript、Python。
靜態(tài)語言:相對(duì)于動(dòng)態(tài)語言來說,在編譯時(shí)變量的數(shù)據(jù)類型就已經(jīng)確定(使用變量之前必須聲明數(shù)據(jù)類型),在編譯時(shí)就會(huì)進(jìn)行類型是否匹配;比如C語言、Java;
03.反射的概念Java反射機(jī)制:在運(yùn)行過程中,對(duì)于任意一個(gè)類,都能知道其所有的屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能調(diào)用其屬性和方法;這種動(dòng)態(tài)獲取類信息和調(diào)用對(duì)象方法的功能,就是Java反射機(jī)制。
既然反射里面有一個(gè)“反”字,那么我們先看看何為“正”。
在Java中,要使用一個(gè)類中的某個(gè)方法,“正向”都是這樣的:
那么反向(反射)要如何實(shí)現(xiàn)?
兩段代碼執(zhí)行的結(jié)果是一樣的,但是“正向”代碼在編譯前,就已經(jīng)明確了要運(yùn)行的類是什么(ArrayList),而第二段代碼,只有在代碼運(yùn)行時(shí),才知道運(yùn)行的類是java.util.ArrayList。
04.反射的作用講到這里,有些同學(xué)可能會(huì)有疑問:“反射有什么用?我明明都已經(jīng)知道了要使用的類是ArrayList,我不能直接new一個(gè)對(duì)象然后執(zhí)行里面的方法么?”
當(dāng)然可以!不過很多場(chǎng)景中,在代碼運(yùn)行之前并不知道需要使用哪個(gè)類,或者說在運(yùn)行的時(shí)候才決定使用哪個(gè)類;
比如有這么一個(gè)功能:“調(diào)用阿里云的人臉識(shí)別API”;這還不簡(jiǎn)單,參考對(duì)方的API文檔,很快就能實(shí)現(xiàn)。
上線一個(gè)月后,領(lǐng)導(dǎo)說:“咱公司開始和騰訊云合作了,人臉識(shí)別的接口改一下吧”。
修改上線運(yùn)行了兩個(gè)月,領(lǐng)導(dǎo)說:“換回來吧”......
當(dāng)然有聰明的程序員會(huì)想到設(shè)置一個(gè)開關(guān)配置,讓開關(guān)決定走哪段代碼邏輯,如果領(lǐng)導(dǎo)哪天想變成亞馬遜云的服務(wù),繼續(xù)寫if-else就好了:
不過還有一種更好的方法:
1.定義一個(gè)接口:
2.多個(gè)實(shí)現(xiàn)類:
3.在調(diào)用人臉識(shí)別功能的代碼中:
如果上面這個(gè)例子,你依然覺得在調(diào)用方法中做if-else判斷,和使用反射實(shí)現(xiàn)并沒有差太多,但是如果程序員A提供接口,程序員B提供實(shí)現(xiàn),程序員C寫客戶端呢?
回憶一下JDBC的使用,比如創(chuàng)建一個(gè)連接:
其中:
程序員A提供接口:Oracle公司(之前的Sun)提供JDBC標(biāo)準(zhǔn)(接口)。程序員B提供實(shí)現(xiàn):各個(gè)數(shù)據(jù)庫廠商提供針對(duì)自家數(shù)據(jù)庫的實(shí)現(xiàn)。程序員C寫客戶端:我等碼農(nóng)在Java中敲代碼訪問數(shù)據(jù)庫。總結(jié)一下Java反射的作用:可以設(shè)計(jì)出更為通用和靈活的架構(gòu),很多框架為了保證其通用性,可以根據(jù)配置加載不用的類,這時(shí)候要用到反射。除此之外:
動(dòng)態(tài)代理:在不改變目標(biāo)對(duì)象方法的情況下對(duì)方法進(jìn)行增強(qiáng),比如使用AOP攔截某些方法打印日志,這就需要通過反射執(zhí)行方法中的內(nèi)容。注解:利用反射機(jī)制,獲取注解并執(zhí)行對(duì)應(yīng)的行為。05.用反射的用法上文中我們知道了Java運(yùn)行期的源文件是class文件(字節(jié)碼),所以要使用反射,那么就需要獲取到字節(jié)碼文件對(duì)象,在Java中,獲取字節(jié)碼文件對(duì)象有三種方式:
調(diào)用某個(gè)類的class屬性:類名.class調(diào)用對(duì)象的getClass()方法:對(duì)象.getClass()使用Class類中的forName()靜態(tài)方法:Class.forName(類的全路徑),建議使用這種方法java.lang.reflect類庫提供了對(duì)反射的支持:
Field:可以使用get和set方法讀取和修改對(duì)象的屬性;Method:可以使用invoke()方法調(diào)用對(duì)象中的方法;Constructor:可以用newInstance()創(chuàng)建新的對(duì)象。06.反射的優(yōu)缺點(diǎn)優(yōu)點(diǎn):在運(yùn)行時(shí)動(dòng)態(tài)獲取類和對(duì)象中的內(nèi)容,極大地提高系統(tǒng)的靈活性和擴(kuò)展性;夸張一些說,反射是框架設(shè)計(jì)的靈魂。
缺點(diǎn):會(huì)有一定的性能損耗,JVM無法對(duì)這些代碼進(jìn)行優(yōu)化;破壞類的封裝性。
總之,可能大家在平時(shí)的開發(fā)過程中,感覺自己并沒有寫過反射相關(guān)的代碼,但是在我們用到的各種開源框架中,反射無處不在。
我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注;關(guān)注我后,可私信發(fā)送數(shù)字【1】,獲取海量學(xué)習(xí)資料。反射機(jī)制和函數(shù)回調(diào)的區(qū)別
看到過濾器跟攔截器的時(shí)候,發(fā)現(xiàn)他們的區(qū)別有一點(diǎn)就是:攔截器是基于java的反射機(jī)制的,而過濾器是基于函數(shù)回調(diào)。
Java反射到底慢在哪里
先陳述一下結(jié)論:java的反射是慢,但是是相對(duì)于直接調(diào)用而言,慢也的確慢了一個(gè)數(shù)量級(jí),不過在有些場(chǎng)景必須使用反射,并且在反射的時(shí)候,可以用一些手段進(jìn)行人工優(yōu)化
再說一下java反射之所以有一點(diǎn)慢的原因
1.java和python比起來,java是靜態(tài)語言類型,也就是說在編譯期java在編譯代碼的時(shí)候就會(huì)進(jìn)行類型的強(qiáng)檢驗(yàn),java會(huì)在編譯期進(jìn)行代碼優(yōu)化,而反射是在運(yùn)行時(shí)發(fā)生的,也就是說那些類型檢查,代碼優(yōu)化的事情放在了運(yùn)行時(shí),這個(gè)自然要耗費(fèi)一點(diǎn)時(shí)間
2.編譯期在運(yùn)行時(shí)很難做一些關(guān)于反射的優(yōu)化,現(xiàn)在的編譯期還不是非常智能,知道你用這段反射代碼需要做什么事情
3.再說一下,調(diào)用實(shí)現(xiàn)過程,在反射調(diào)用過程中,執(zhí)行者叫MethodAccessor,我記得這個(gè)對(duì)象是懶加載的,也就是說有可能第一次反射調(diào)用耗時(shí)可能會(huì)更長(zhǎng)一點(diǎn),并且在調(diào)用的時(shí)候method.invoke方法還要對(duì)參數(shù)數(shù)組進(jìn)行包裝,可能涉及到參數(shù)類型適配,裝包拆包也有消耗,其實(shí)說到底,還是不知道具體的參數(shù)類型
好了,文章到此結(jié)束,希望可以幫助到大家。
本文鏈接:http://xinin56.com/qianduan/2315.html