導航:首頁 > 編程語言 > java反射的優缺點

java反射的優缺點

發布時間:2022-04-26 15:33:34

java反射機制的作用 及其它的好處

反射其實就是程序能夠自檢查自身信息。就像程序會照鏡子反光看自己。

在程序中可以檢查某個類中的方法屬性等信息,並且能夠動態調用。
這樣可以寫出很靈活的程序。
比如要把一個對象中的數據到另外一個對象中,規則是屬性名相同就,
就可以用反射來做,不需要指定每個屬性的名字,只要動態從類中取得信息,
再判斷屬性名是否相同即可。當然應用還有很多。

反射可以結合Java的位元組碼,使用ASM和cglib等庫,還能動態生成類。
hibernate的延遲載入,spring的AOP都是這么實現的

反射給Java帶來了一些動態性。不過雖然很好,但畢竟還是有一定局限性的。另外ASM,cglib使用還是不放便。因此一些純動態語言現在是一個重要發展趨勢,比如ruby,python等,程序很容易動態生成。

Ⅱ java 反射有什麼用

反射就是把java類中的各種成分映射成為相應的java類。例如:一個java類用一個Class類的對象來表示,一個類中的組成部分:成員變數、方法、構造函數、包等等信息也用一個個java類來表示,就像汽車是一個類,汽車中的發動機,變速箱等等也是一個個的java類,表示java類的Class類顯然要提供一系列的方法,來獲得其中的變數,方法,構造函數,修飾符,包等信息,這些信息就是用相應類的實例對象來表示,它們是Field、Method、Constructor、Package等等

在平時的編程中,反射基本用不到,但是在編寫框架的時候,反射用的就多了,比如你要使用某一個類進行操作,但是這個類是用戶通過配置文件配置進來的,你需要先讀配置文件,然後拿到這個類的全類名:比如com.onede4..Person,然後在利用反射API來做操作

Ⅲ Java反射的性能為什麼比直接調用慢一個數量級左右

反射肯定比直接調用慢

這個毋庸置疑了,我這篇文章也不是證明反射有多高效的。

現在的快遞哥很火,那我們就舉個快遞的例子。如果快遞員就在你住的小區,那麼你報一個地址:xx棟xx號,那麼快遞員就可以馬上知道你在哪裡,直接就去到你家門口;但是,如果快遞員是第一次來你們這里,他是不是首先得查查網路地圖,看看怎麼開車過去,然後到了小區是不是得先問問物管xx棟怎麼找,然後,有可能轉在樓下轉了兩個圈才到了你的門前。

我們看上面這個場景,如果快遞員不熟悉你的小區,是不是會慢點,他的時間主要花費在了查找網路地圖,詢問物業管理。OK,反射也是一樣,因為我事先什麼都不知道,所以我得花時間查詢一些其他資料,然後我才能找到你。大家有興趣可以查看反射的實現原理,以及MetaData的相關概念。

反射到底比直接調用慢多少?

好了,我們知道反射肯定慢的,那麼是不是反射就不能用了呢?有些人一聽到慢,就非常著急的下結論,反射怎樣怎樣不行,怎樣怎樣不能用。但是,同學,反射到底比直接調用慢多少,你造嗎,能給我個實際的數據嗎?很多人其實對性能只有個模糊的概念,而沒有數值支撐。之前我給同事找了一個動態解析表達式的類庫,他覺得不太好用,他很聰明,很快的找到了用DataTale.Compute可以實現公式的動態解析。我問他,這個方法和我給的類庫性能上有什麼區別?他跟我說,這個已經很快了,執行1秒都不到。我一聽,就覺得不對勁,你的思想還停留在秒級,跟我談什麼性能?

怎麼去判斷一個函數的性能?因為函數的執行太快太快了,你需要一個放慢鏡,這樣才能捕捉到他的速度。怎麼做?把一個函數執行一百萬遍或者一千萬遍,你才能真正了解一個函數的性能。也就是,你如果想判斷性能,你就不能還停留在秒級,毫秒級的概念,你必須用另外一個概念替代,才能知道真正的性能。結果我同事把這兩種方法執行了100w遍,確實,我提供的類庫比他的快了8秒。

好了,現在拿我早兩天提供的工廠方法來做測試,其中CodeTimer的實現參考趙大神的文章《一個簡單的性能計數器:CodeTimer》:

測試方法如下:

代碼如下
復制代碼

[Test]
public void TestReflector()
{
CodeTimer.Time("Direct", 100 * 10000,
() =>
{
var instance = new ConnectionTest();
});

CodeTimer.Time("Reflect", 100 * 10000,
() =>
{
this.GetType().Assembly.CreateInstance("TestPropertyGrid.ConnectionTest");
});
}

測試結果如下:

Direct
Time Elapsed: 25ms
CPU Cycles: 57,582,163
Gen 0: 14
Gen 1: 0

Reflect
Time Elapsed: 3,231ms
CPU Cycles: 8,001,720,795
Gen 0: 269
Gen 1: 1

看到沒,我們的放大鏡起作用了,現在我們大概可以下這么一個結論:在執行100萬遍的時候,反射大概把直接調用慢50~100倍。100倍,咋一看,是相差很大的,但是,我前文說了,別著急下結論,你要看看前提條件。自古我們就喜歡斷章取義,比如「以德報怨」這個成語,好像古人說讓我們遇到不好的,你不能怨恨,要更好的對待他人,別人打你左臉一巴掌,你應該把右臉伸過去讓他再打一下。但實際這個成語是怎樣的呢?

或曰:「以德報怨,何如?」
子曰:「何以報德?以直報怨,以德報德」

老孔的意思其實是如果別人對你好,那麼你就對他好,要是他招你惹你了,你就干他娘的!你看,傻眼了吧?
有多少情況下需要考慮反射帶來的影響?

我認為這個情況是非常非常少的,絕大多數的我們根本就無需考慮這個。就上我上一篇文章提到的工廠,你程序有多少個實體,有100萬個嗎?如果你只是在彈出窗口的時候new一下,這個百萬分之十秒的影響對你很重要嗎?

另外,有些人講,我要是真有這種需求,要把一個對象new一百萬遍,那不還是慢嗎?這種情況有沒有,有!比如我有100w條記錄,需要取出來,然後通過反射賦值到一個Model類中。

但是對於這種情況,如果你真是這么想的話,我只能說,你坐辦公室坐久了,腦袋生銹了,該去爬爬山,泡泡妞了。如果你需要對一個對象反射一百萬遍,那麼你就應該緩存這個對象了。拿我們上面那個例子來說,如果這個快遞員給小區的人送一百萬遍的快遞還認不得路,每次都還得網路地圖,然後問物業管理,你丫的你還沒把他開掉了,那你腦袋不是秀逗了,要不就是任性的有錢人。

上面代碼如果緩存之後執行一百萬遍,跟直接調用有多大的區別?我這里就不貼代碼了,免得你們直接看結果沒有意思,自己把代碼敲一遍,印象更深刻。

那麼,還有沒有更快的辦法,有。比如你的快遞員開始用的是IPHONE4,現在可以考慮給他買個6+。在.net中,提供了Emit的相關方法來讓你更快的反射。這里送你一個通過反射快速給Model賦值的輪子「Dapper」,自己回家造去。
編程中是否應該使用反射?

其實看完上面的文字,我相信你們都有了一個初步的判斷,而我的看法是:絕大多數的情況下你都可以用反射。

如果你覺得是因為反射導致你程序慢的話,那麼,請先用放慢鏡好好觀察一下,到底是不是反射的問題。如果你確定是反射的問題,那麼你再好好的考慮下是不是你沒有用對反射,是不是像上面那個走了一百萬遍都不認識路的快遞員一樣。最後,如果你覺得性能上還是不夠,那麼我建議你升級下硬體吧,把硬體性能上升個3%總好過你請個牛逼的工程師來幫你做這種極限的優化,有一句話我覺得很對「工程師比伺服器要昂貴的多」。如果你還非得跟我較勁,那麼,沒辦法了,你程序對性能的要求已經超出了本文討論的范疇,如果你真有這種需求了,我覺得你也沒有必要看我這篇文章了,因為你已經足夠牛逼到對系統語言都有深入了解了。

大多時候,我們會把程序的性能歸結於編程語言,或者使用了反射等技術,而甚少去關心自己的代碼,這種心態會導致你技術的發展越來越緩慢,因為你已經失去了求知的慾望,以及一顆追求技術進步的心。請你記住,更多的時候,影響我們程序性能的,是你編程的思想,你對待編碼的態度!
總結

好吧,說了這么多,估計很多人直接就拖到文章末尾然後因為文章碼了這么多字而默默點了個贊,那麼,我在最後給大家奉獻一下本文的精華:

反射大概比直接調用慢50~100倍,但是需要你在執行100萬遍的時候才會有所感覺
判斷一個函數的性能,你需要把這個函數執行100萬遍甚至1000萬遍
如果你只是偶爾調用一下反射,請忘記反射帶來的性能影響
如果你需要大量調用反射,請考慮緩存。
你的編程的思想才是限制你程序性能的最主要的因素

Ⅳ JAVA中的反射和反射機制到底是什麼啊

Java Reflection (JAVA反射) 詳解
Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象(根據安全性限制),無需提前硬編碼目標類。這些特性使得反射特別適用於創建以非常普通的方式與對象協作的庫。例如,反射經常在持續存儲對象為資料庫、XML或其它外部格式的框架中使用。Java reflection 非常有用,它使類和數據結構能按名稱動態檢索相關信息,並允許在運行著的程序中操作這些信息。Java 的這一特性非常強大,並且是其它一些常用語言,如 C、C++、Fortran 或者 Pascal 等都不具備的。
但反射有兩個缺點。第一個是性能問題。用於欄位和方法接入時反射要遠慢於直接代碼。性能問題的程度取決於程序中是如何使用反射的。如果它作為程序運行中相對很少涉及的部分,緩慢的性能將不會是一個問題。即使測試中最壞情況下的計時圖顯示的反射操作只耗用幾微秒。僅反射在性能關鍵的應用的核心邏輯中使用時性能問題才變得至關重要。
許多應用中更嚴重的一個缺點是使用反射會模糊程序內部實際要發生的事情。程序人員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術會帶來維護問題。反射代碼比相應的直接代碼更復雜,正如性能比較的代碼實例中看到的一樣。解決這些問題的最佳方案是保守地使用反射——僅在它可以真正增加靈活性的地方——記錄其在目標類中的使用。 Reflection是Java 程序開發語言的特徵之一,它允許運行中的 Java 程序對自身進行檢查,或者說"自審",並能直接操作程序的內部屬性。例如,使用它能獲得 Java 類中各成員的名稱並顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。JavaBean 是 reflection 的實際應用之一,它能讓一些工具可視化的操作軟體組件。這些工具通過 reflection 動態的載入並取得 Java 組件(類) 的屬性。1. 一個簡單的例子考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
按如下語句執行:java DumpMethods java.util.Stack
它的結果輸出為:public java.lang.Object java.util.Stack.push(java.lang.Object)public synchronized java.lang.Object java.util.Stack.pop()public synchronized java.lang.Object java.util.Stack.peek()public boolean java.util.Stack.empty()public synchronized int java.util.Stack.search(java.lang.Object)
這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。這個程序使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。
2.開始使用 Reflection用於 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時候必須要遵循三個步驟:第一步是獲得你想操作的類的 java.lang.Class 對象。在運行中的 Java 程序中,用 java.lang.Class 類來描述類和介面等。
下面就是獲得一個 Class 對象的方法之一:Class c = Class.forName("java.lang.String");
這條語句得到一個 String 類的類對象。還有另一種方法,如下面的語句:Class c = int.class;
或者Class c = Integer.TYPE;
它們可獲得基本類型的類信息。其中後一種方法中訪問的是基本類型的封裝類 (如 Integer) 中預先定義好的 TYPE 欄位。第二步是調用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。一旦取得這個信息,就可以進行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:Class c = Class.forName("java.lang.String");Method m[] = c.getDeclaredMethods();System.out.println(m[0].toString());
它將以文本方式列印出 String 中定義的第一個方法的原型。在下面的例子中,這三個步驟將為使用 reflection 處理特殊應用程序提供例證。模擬 instanceof 操作符得到類信息之後,通常下一個步驟就是解決關於 Class 對象的一些基本的問題。例如,Class.isInstance 方法可以用於模擬 instanceof 操作符:class A {
}public class instance1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("A");
boolean b1 = cls.isInstance(new Integer(37));
System.out.println(b1);
boolean b2 = cls.isInstance(new A());
System.out.println(b2);
} catch (Throwable e) {
System.err.println(e);
}
}
}
在這個例子中創建了一個 A 類的 Class 對象,然後檢查一些對象是否是 A 的實例。Integer(37) 不是,但 new A()是。
3.找出類的方法找出一個類中定義了些什麼方法,這是一個非常有價值也非常基礎的 reflection 用法。下面的代碼就實現了這一用法:import java.lang.reflect.*;public class method1 {
private int f1(Object p, int x) throws NullPointerException {
if (p == null)
throw new NullPointerException();
return x;
}public static void main(String args[]) {
try {
Class cls = Class.forName("method1");
Method methlist[] = cls.getDeclaredMethods();
for (int i = 0; i < methlist.length; i++) {
Method m = methlist[i];
System.out.println("name = " + m.getName());
System.out.println("decl class = " + m.getDeclaringClass());
Class pvec[] = m.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
Class evec[] = m.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("return type = " + m.getReturnType());
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個程序首先取得 method1 類的描述,然後調用 getDeclaredMethods 來獲取一系列的 Method 對象,它們分別描述了定義在類中的每一個方法,包括 public 方法、protected 方法、package 方法和 private 方法等。如果你在程序中使用 getMethods 來代替 getDeclaredMethods,你還能獲得繼承來的各個方法的信息。
取得了 Method 對象列表之後,要顯示這些方法的參數類型、異常類型和返回值類型等就不難了。這些類型是基本類型還是類類型,都可以由描述類的對象按順序給出。輸出的結果如下:name = f1decl class = class method1param #0 class java.lang.Objectparam #1 intexc #0 class java.lang.NullPointerExceptionreturn type = int-----
name = maindecl class = class method1param #0 class [Ljava.lang.String;return type = void4.獲取構造器信息獲取類構造器的用法與上述獲取方法的用法類似,如:import java.lang.reflect.*;public class constructor1 {
public constructor1() {
}protected constructor1(int i, double d) {
}public static void main(String args[]) {
try {
Class cls = Class.forName("constructor1");
Constructor ctorlist[] = cls.getDeclaredConstructors();
for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name = " + ct.getName());
System.out.println("decl class = " + ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個例子中沒能獲得返回類型的相關信息,那是因為構造器沒有返回類型。這個程序運行的結果是:name = constructor1decl class = class constructor1-----
name = constructor1decl class = class constructor1param #0 intparam #1 double5.獲取類的欄位(域)
找出一個類中定義了哪些數據欄位也是可能的,下面的代碼就在干這個事情:import java.lang.reflect.*;public class field1 {
private double d;
public static final int i = 37;
String s = "testing";public static void main(String args[]) {
try {
Class cls = Class.forName("field1");
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name = " + fld.getName());
System.out.println("decl class = " + fld.getDeclaringClass());
System.out.println("type = " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個例子和前面那個例子非常相似。例中使用了一個新東西 Modifier,它也是一個 reflection 類,用來描述欄位成員的修飾語,如「private int」。這些修飾語自身由整數描述,而且使用 Modifier.toString 來返回以「官方」順序排列的字元串描述 (如「static」在「final」之前)。這個程序的輸出是:name = ddecl class = class field1type = doublemodifiers = private-----
name = idecl class = class field1type = intmodifiers = public static final-----
name = sdecl class = class field1type = class java.lang.Stringmodifiers =
和獲取方法的情況一下,獲取欄位的時候也可以只取得在當前類中申明了的欄位信息 (getDeclaredFields),或者也可以取得父類中定義的欄位 (getFields) 。
6.根據方法的名稱來執行方法文本到這里,所舉的例子無一例外都與如何獲取類的信息有關。我們也可以用 reflection 來做一些其它的事情,比如執行一個指定了名稱的方法。下面的示例演示了這一操作:import java.lang.reflect.*;
public class method2 {
public int add(int a, int b) {
return a + b;
}
public static void main(String args[]) {
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod("add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = meth.invoke(methobj, arglist);
Integer retval = (Integer) retobj;
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
}
假如一個程序在執行的某處的時候才知道需要執行某個方法,這個方法的名稱是在程序的運行過程中指定的 (例如,JavaBean 開發環境中就會做這樣的事),那麼上面的程序演示了如何做到。上例中,getMethod用於查找一個具有兩個整型參數且名為 add 的方法。找到該方法並創建了相應的Method 對象之後,在正確的對象實例中執行它。執行該方法的時候,需要提供一個參數列表,這在上例中是分別包裝了整數 37 和 47 的兩個 Integer 對象。執行方法的返回的同樣是一個 Integer 對象,它封裝了返回值 84。
7.創建新的對象對於構造器,則不能像執行方法那樣進行,因為執行一個構造器就意味著創建了一個新的對象 (准確的說,創建一個對象的過程包括分配內存和構造對象)。所以,與上例最相似的例子如下:import java.lang.reflect.*;public class constructor2 {
public constructor2() {
}public constructor2(int a, int b) {
System.out.println("a = " + a + " b = " + b);
}public static void main(String args[]) {
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
} catch (Throwable e) {
System.err.println(e);
}
}
}
根據指定的參數類型找到相應的構造函數並執行它,以創建一個新的對象實例。使用這種方法可以在程序運行時動態地創建對象,而不是在編譯的時候創建對象,這一點非常有價值。
8.改變欄位(域)的值reflection 的還有一個用處就是改變對象數據欄位的值。reflection 可以從正在運行的程序中根據名稱找到對象的欄位並改變它,下面的例子可以說明這一點:import java.lang.reflect.*;public class field2 {
public double d;public static void main(String args[]) {
try {
Class cls = Class.forName("field2");
Field fld = cls.getField("d");
field2 f2obj = new field2();
System.out.println("d = " + f2obj.d);
fld.setDouble(f2obj, 12.34);
System.out.println("d = " + f2obj.d);
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個例子中,欄位 d 的值被變為了 12.34。
9.使用數組本文介紹的 reflection 的最後一種用法是創建的操作數組。數組在 Java 語言中是一種特殊的類類型,一個數組的引用可以賦給 Object 引用。觀察下面的例子看看數組是怎麼工作的:import java.lang.reflect.*;public class array1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("java.lang.String");
Object arr = Array.newInstance(cls, 10);
Array.set(arr, 5, "this is a test");
String s = (String) Array.get(arr, 5);
System.out.println(s);
} catch (Throwable e) {
System.err.println(e);
}
}
}
例中創建了 10 個單位長度的 String 數組,為第 5 個位置的字元串賦了值,最後將這個字元串從數組中取得並列印了出來。

Ⅳ JAVA中反射是什麼

JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。

Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。而這也是Java被視為動態語言的一個關鍵性質。

Java反射的功能是在運行時判斷任意一個對象所屬的類,在運行時構造任意一個類的對象,在運行時判斷任意一個類所具有的成員變數和方法,在運行時調用任意一個對象的方法,生成動態代理。

(5)java反射的優缺點擴展閱讀:

JAVA中反射實例:

1、Class superClass=clazz.getSuperclass();//獲取父類。

System.out.println("getSuperclass:"+superClass)。

2、Class[] interfaces=clazz.getInterfaces();//獲取實現介面。

System.out.println("getInterfaces:"+interfaces.length)。

3、Constructor[] cons=clazz.getConstructors();//構造方法。

System.out.println("getConstructors:"+cons.length)。

參考資料來源:網路: JAVA反射機制

Ⅵ 怎麼理解Java中的反射,作用是什麼

反射是審查元數據並收集關於它的類型信息的能力。元數據(編譯以後的最基本數據單元)就是一大堆的表,當編譯程序集或者模塊時,編譯器會創建一個類定義表,一個欄位定義表,和一個方法定義表等.

反射的主要作用是用來擴展系統和動態調用程序集。
所謂擴展系統就是先把系統寫好,系統裡面定義介面,後面開發的人去寫介面的代碼。
此時該系統就要用反射了,系統用反射調用介面,當介面沒寫,系統利用反射就不會不會出錯,此時就等於沒實現此功能而已,當介面被人寫好了,系統就會自動調用介面的功能展現在系統上。
即反射實現即插即用功能。

動態調用程序集就是利用反射去調用編譯好的dll,當然此時的dll沒有被引用到你所建的工程裡面。
當你編譯你的工程時,不會編譯你調用的dll,當你運行到調用dll時,此時才會去調用dll,判斷是否有語法語義,等編譯,運行的錯誤。
這樣利用反射具有一定靈活性,就是不用從你的工程調用dll,還有就是dll可隨時改變(當然介面還是要對應),不需改變你所建的工程。

總之反射最好的好處就是新建工程時後不須一定要寫好dll,可新建完工程後,後期寫dll也可以。即所謂後期綁定。當然利用反射是耗資源的,損失效率,如果不是在上面的場合利用此技術,可能不會帶來好處,反而是壞處。

Ⅶ java反射的性能為什麼低

java反射需要將內存中的對象進行解析,涉及到與底層c語言的交互,速度會比較慢。
java反射得到的每一個Method都有一個root,不暴漏給外部,而是每次一個Method。具體的反射調用邏輯是委託給MethodAccessor的,而accessor對象會在第一次invoke的時候才創建,是一種lazy init方式。而且默認Class類會cache method對象。目前MethodAccessor的實現有兩種,通過設置inflation,一個native方式,一種生成java bytecode方式。native方式啟動快,但運行時間長了不如java方式,個人感覺應該是java方式運行長了,jit compiler可以進行優化。所以JDK6的實現,在native方式中,有一個計數器,當調用次數達到閥值,就會轉為使用java方式。默認值是15。java方式的實現,基本和非反射方式相同。

Ⅷ java反射的作用。

1.可以通過反射機制發現對象的類型,發現類型的方法/屬性/構造器
2.可以創建對象並訪問任意對象方法和屬性

Ⅸ 大神解釋一下java反射有什麼作用

java的反射機制就是增加程序的靈活性,避免將程序寫死到代碼里,

例如: 實例化一個 person()對象, 不使用反射, new person(); 如果想變成 實例化 其他類, 那麼必須修改源代碼,並重新編譯。
使用反射: class.forName("person").newInstance(); 而且這個類描述可以寫到配置文件中,如 *.xml, 這樣如果想實例化其他類,只要修改配置文件的"類描述"就可以了,不需要重新修改代碼並編譯。

像spring,struts等這些開源框架的實現都用到了反射機制。

Ⅹ java的反射技術有什麼用

一、反射的概述

JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼文件對應的Class類型的對象.


以上的總結就是什麼是反射
反射就是把java類中的各種成分映射成一個個的Java對象
例如:一個類有:成員變數、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把個個組成部分映射成一個個對象。(其實:一個類中這些成員方法、構造方法、在加入類中都有一個類來描述)
如圖是類的正常載入過程:反射的原理在與class對象。
熟悉一下載入的時候:Class對象的由來是將class文件讀入內存,並為之創建一個Class對象。

希望對您有所幫助!~

閱讀全文

與java反射的優缺點相關的資料

熱點內容
銀河麒麟字體庫存在哪個文件夾 瀏覽:956
魔獸加丁伺服器的航空叫什麼 瀏覽:152
花冠改裝案例哪個app多 瀏覽:515
成績單app哪個好用 瀏覽:140
北美程序員vs國內程序員 瀏覽:181
php解析xml文檔 瀏覽:121
石墨文檔APP怎麼橫屏 瀏覽:185
牆主鋼筋加密和非加密怎麼看 瀏覽:144
金山區文件夾封套定製 瀏覽:708
soho程序員 瀏覽:672
java位元組截取 瀏覽:525
php提交作業 瀏覽:815
房產還沒解壓可以辦理贈予嗎 瀏覽:224
java毫秒轉分鍾 瀏覽:753
模式識別中文pdf 瀏覽:774
c語言平均數字編譯錯誤 瀏覽:170
單片機算交流 瀏覽:45
php自適應網站 瀏覽:467
2b2t伺服器怎麼獲得許可權 瀏覽:816
c語言javaphp 瀏覽:804