- 一. 基礎(chǔ)概念
- 二. new 對(duì)象和反射創(chuàng)建對(duì)象的效率對(duì)比
- 三. 反射和new 的使用場(chǎng)景
一. 基礎(chǔ)概念
Java中,一般我們創(chuàng)建一個(gè)對(duì)象可能會(huì)選擇new一下個(gè)實(shí)例。但是隨著我們技術(shù)的不斷提升,我們也學(xué)習(xí)到了,可以通過(guò)反射技術(shù)實(shí)現(xiàn)對(duì)象的創(chuàng)建。
可是,你有沒(méi)有想一下,什么時(shí)候我們改用new創(chuàng)建對(duì)象,什么時(shí)候我們改用反射創(chuàng)建對(duì)象呢?
兩者創(chuàng)建對(duì)象的效率又是如何呢?
//new方式創(chuàng)建對(duì)象
ReflectDemoreflectDemo=newReflectDemo();
//反射創(chuàng)建對(duì)象反射創(chuàng)建對(duì)象的三種方式
(1)ClassreflectDemoClass=ReflectDemo.class;
(2)Class>aClass=Class.forName("com.whale.springtransaction.transactiondemo.reflectdemo.ReflectDemo");
(3)Class?extends?Class>aClass=reflectDemoClass.getClass();
基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
- 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
- 視頻教程:https://doc.iocoder.cn/video/
二. new 對(duì)象和反射創(chuàng)建對(duì)象的效率對(duì)比
//測(cè)試代碼如下
publicclassReflectDemo{
publicstaticvoidmain(String[]args)throwsIllegalAccessException,InstantiationException{
proxyObject();
newObject();
}
//new創(chuàng)建對(duì)象
//5
publicstaticvoidnewObject(){
longstartTime=System.currentTimeMillis();
inti;
for(i=0;i100000000;i++){
ReflectDemoreflectDemo=newReflectDemo();
}
if(i==100000000){
longendTime=System.currentTimeMillis();
System.out.println("new耗時(shí)為:"+(endTime-startTime));
}
}
//反射創(chuàng)建對(duì)象
//30
publicstaticvoidproxyObject()throwsIllegalAccessException,InstantiationException{
longstartTime=System.currentTimeMillis();
ClassreflectDemoClass=ReflectDemo.class;
inti;
for(i=0;i100000000;i++){
ReflectDemoreflectDemo=reflectDemoClass.newInstance();
}
if(i==100000000){
longendTime=System.currentTimeMillis();
System.out.println("反射耗時(shí)為:"+(endTime-startTime));
}
}
}
最終我們發(fā)現(xiàn),new 100000000
個(gè)對(duì)象和反射創(chuàng)建 100000000 個(gè)對(duì)象,效率相差了很多倍。
所以下面我們來(lái)探討一下為什么這么大差別?
首先第一點(diǎn),一般我們的Java代碼是需要編譯后在虛擬機(jī)里面運(yùn)行的。
我們一般都是通過(guò)一個(gè)前端編輯器,比如javac,把java文件轉(zhuǎn)為class文件。
接下來(lái),程序運(yùn)行期間,可能會(huì)通過(guò)一個(gè)JIT,即時(shí)編譯器將字節(jié)碼文件轉(zhuǎn)換為計(jì)算機(jī)認(rèn)識(shí)的機(jī)器碼文件。
另外一種可能是通過(guò)一個(gè)AOT編譯器,直接把java文件編譯為本地機(jī)器碼文件。其中JIT在程序運(yùn)行期會(huì)對(duì)程序進(jìn)行優(yōu)化,但是反射是通過(guò)動(dòng)態(tài)解析的方式,因此可能無(wú)法執(zhí)行某些java虛擬機(jī)的優(yōu)化。
總結(jié)起來(lái)有下面幾個(gè)原因:
Method#invoke
方法會(huì)對(duì)參數(shù)做封裝和解封操作
- 需要檢查方法可見(jiàn)
- 需要校驗(yàn)參數(shù)
- 反射方法難以內(nèi)聯(lián)
- JIT 無(wú)法優(yōu)化
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能
三. 反射和new 的使用場(chǎng)景
反射的部分使用場(chǎng)景
- Spring通過(guò)反射來(lái)幫我們實(shí)例化對(duì)象,并放入到Ioc容器中
-
使用JDBC鏈接數(shù)據(jù)庫(kù)時(shí)加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)
Class.forName()
- 逆向代碼 例如反編譯
- 利用反射,在泛型為int的arryaList集合中存放一個(gè)String類型的對(duì)象
new 對(duì)象和反射的區(qū)別
-
new的對(duì)象無(wú)法訪問(wèn)其中的私有屬性,反射出來(lái)的可以通過(guò)設(shè)置
setAccessible()
方法來(lái)省略訪問(wèn)權(quán)限符。 - new必須要知道類名,而反射創(chuàng)建對(duì)象不需要知道類型也可以創(chuàng)建
審核編輯 :李倩
-
JAVA
+關(guān)注
關(guān)注
19文章
2947瀏覽量
104373 -
數(shù)據(jù)庫(kù)
+關(guān)注
關(guān)注
7文章
3739瀏覽量
64174 -
編譯器
+關(guān)注
關(guān)注
1文章
1608瀏覽量
48979
原文標(biāo)題:Java反射和new效率對(duì)比,差距有多大?
文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論