當前位置: 妍妍網 > 碼農

Java反射和new效率對比,差距有多大?

2024-06-19碼農

Java中,一般我們建立一個物件可能會選擇new一下個例項。但是隨著我們技術的不斷提升,我們也學習到了,可以透過反射技術實作物件的建立。

可是,你有沒有想一下,什麽時候我們改用new建立物件,什麽時候我們改用反射建立物件呢?

兩者建立物件的效率又是如何呢?

//new 方式建立物件
ReflectDemo reflectDemo = new ReflectDemo();
//反射建立物件 反射建立物件的三種方式
(1) class<ReflectDemo> reflectDemo class = ReflectDemo. class;
(2) class<?> a class = class.forName ("com.whale.springtransaction.transactiondemo.reflectdemo.ReflectDemo");
(3) class<? extends class> a class = reflectDemo class.get class ();

二. new 物件和反射建立物件的效率對比

//測試程式碼如下
public classReflectDemo{
publicstaticvoidmain(String[] args)throws IllegalAccessException, InstantiationException {
proxyObject();
newObject();
 }
//new 建立物件
//5
publicstaticvoidnewObject(){
long startTime = System.currentTimeMillis ();
int i;
for (i = 0; i < 100000000; i++) {
ReflectDemo reflectDemo = new ReflectDemo ();
}
if (i == 100000000) {
long endTime = System.currentTimeMillis ();
System.out.println ("new耗時為:" + (endTime - startTime));
}
 }
//反射 建立物件
//30
publicstaticvoidproxyObject()throws IllegalAccessException, InstantiationException {
long startTime = System.currentTimeMillis ();
class<ReflectDemo> reflectDemo class = ReflectDemo. class;
int i;
for (i = 0; i < 100000000; i++) {
ReflectDemo reflectDemo = reflectDemo class.newInstance ();
}
if (i == 100000000) {
long endTime = System.currentTimeMillis ();
System.out.println ("反射耗時為:" + (endTime - startTime));
}
 }
}

最終我們發現, new 100000000 個物件和反射建立 100000000 個物件,效率相差了很多倍。

所以下面我們來探討一下為什麽這麽大差別?

首先第一點,一般我們的Java程式碼是需要編譯後在虛擬機器裏面執行的。

我們一般都是透過一個前端編輯器,比如javac,把java檔轉為 class檔。

接下來,程式執行期間,可能會透過一個JIT,即時編譯器將字節碼檔轉換為電腦認識的機器碼檔。

另外一種可能是透過一個AOT編譯器,直接把java檔編譯為本地機器碼檔。其中JIT在程式執行期會對程式進行最佳化,但是反射是透過動態解析的方式,因此可能無法執行某些java虛擬機器的最佳化。

總結起來有下面幾個原因:

Method#invoke 方法會對參數做封裝和解封操作

  • 需要檢查方法可見

  • 需要校驗參數

  • 反射方法難以行內

  • JIT 無法最佳化

  • 三. 反射和new 的使用場景

    反射的部份使用場景

    1. Spring透過反射來幫我們例項化物件,並放入到Ioc容器中

    2. 使用JDBC連結資料庫時載入資料庫驅動 class.forName()

    3. 逆向程式碼 例如反編譯

    4. 利用反射,在泛型為int的arryaList集合中存放一個String型別的物件

    new 物件和反射的區別

    1. new的物件無法存取其中的私有內容,反射出來的可以透過設定 setAccessible() 方法來省略存取許可權符。

    2. new必須要知道類名,而反射建立物件不需要知道型別也可以建立

    來源:blog.csdn.net/sunny_json/article/details/113047372

    >>

    END

    精品資料,超贊福利,免費領

    微信掃碼/長按辨識 添加【技術交流群

    群內每天分享精品學習資料

    最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎並行JVMMySQLRedisSpringSpringMVCSpringBootSpringCloud訊息佇列等多個型別),歡迎您的使用。

    👇👇

    👇點選"閱讀原文",獲取更多資料(持續更新中