Java反射和new效率對比
阿新 • • 發佈:2021-02-01
一 基礎概念
Java中,一般我們建立一個物件可能會選擇new一下個例項。但是隨著我們技術的不斷提升,我們也學習到了,可以通過反射技術實現物件的建立。
可是,你有沒有想一下,什麼時候我們改用new建立物件,什麼時候我們改用反射建立物件呢?
兩者建立物件的效率又是如何呢?
//new 方式建立物件
ReflectDemo reflectDemo = new ReflectDemo();
//反射建立物件 反射建立物件的三種方式
(1)Class<ReflectDemo> reflectDemoClass = ReflectDemo.class;
( 2)Class<?> aClass = Class.forName ("com.whale.springtransaction.transactiondemo.reflectdemo.ReflectDemo");
(3)Class<? extends Class> aClass = reflectDemoClass.getClass ();
二 new 物件和反射建立物件的效率對比
//測試程式碼如下
public class ReflectDemo {
public static void main (String[] args) throws IllegalAccessException, InstantiationException {
proxyObject();
newObject();
}
//new 建立物件
//5
public static void newObject(){
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
public static void proxyObject() throws IllegalAccessException, InstantiationException {
long startTime = System.currentTimeMillis ();
Class<ReflectDemo> reflectDemoClass = ReflectDemo.class;
int i;
for (i = 0; i < 100000000; i++) {
ReflectDemo reflectDemo = reflectDemoClass.newInstance ();
}
if (i == 100000000) {
long endTime = System.currentTimeMillis ();
System.out.println ("反射耗時為:" + (endTime - startTime));
}
}
}
最終我們發現,new 100000000 個物件和反射建立 100000000 個物件,效率相差了很多倍。
所以下面我們來探討一下為什麼這麼大差別?
(1)首先第一點,一般我們的Java程式碼是需要編譯後在虛擬機器裡面執行的。
首先我們一般都是通過一個前端編輯器,比如javac,把java檔案轉為class檔案。
接下來,程式執行期間,可能會通過一個JIT,即時編譯器將位元組碼檔案轉換為計算機認識的機器碼檔案。
另外一種可能是通過一個AOT編譯器,直接把java檔案編譯為本地機器碼檔案。其中JIT在程式執行期會對程式進行優化,但是反射是通過動態解析的方式,因此可能無法執行某些java虛擬機器的優化。
總結起來有下面幾個原因:
1.Method#invoke 方法會對引數做封裝和解封操作
- 需要檢查方法可見
- 需要校驗引數
- 反射方法難以內聯
- JIT 無法優化
三 反射和new 的使用場景
反射的部分使用場景
1.Spring通過反射來幫我們例項化物件,並放入到Ioc容器中
2.使用JDBC連結資料庫時載入資料庫驅動Class.forName()
3.逆向程式碼 例如反編譯
4.利用反射,在泛型為int的arryaList集合中存放一個String型別的物件
//new 物件和反射的區別
1.new的物件無法訪問其中的私有屬性,反射出來的可以通過設定setAccessible()方法來省略訪問許可權符。
2.new必須要知道類名,而反射建立物件不需要知道型別也可以建立