欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Java Reflection
Java動(dòng)態(tài)程序設計:反射介紹
使用運行的類(lèi)的信息使你的程序設計更加靈活

反射授予了你的代碼訪(fǎng)問(wèn)裝載進(jìn)JVM內的Java類(lèi)的內部信息的權限,并且允許你編寫(xiě)在程序執行期間與所選擇的類(lèi)的一同工作的代碼,而不是在源代碼中。這種機制使得反射成為創(chuàng )建靈活的應用程序的強大工具,但是要小心的是,如果使用不恰當,反射會(huì )帶來(lái)很大的副作用。在這篇文章中,軟件咨詢(xún)顧問(wèn)Dennis Sosnoski 介紹了反射的使用,同時(shí)還介紹了一些使用反射所要付出的代價(jià)。在這里,你可以找到Java反射API是如何在運行時(shí)讓你鉤入對象的。

在第一部分,我向你介紹了Java程序設計的類(lèi)以及類(lèi)的裝載。那篇文章中描述了很多出現在Java二進(jìn)制類(lèi)格式中的信息,現在我來(lái)介紹在運行時(shí)使用反射API訪(fǎng)問(wèn)和使用這些信息的基礎。為了使那些已經(jīng)了解反射基礎的開(kāi)發(fā)人員對這些事情感興趣,我還會(huì )介紹一些反射與直接訪(fǎng)問(wèn)的在性能方面的比較。

使用反射與和metadata(描述其它數據的數據)一些工作的Java程序設計是不同的。通過(guò)Java語(yǔ)言反射來(lái)訪(fǎng)問(wèn)的元數據的特殊類(lèi)型是在JVM內部的類(lèi)和對象的描述。反射使你可以在運行時(shí)訪(fǎng)問(wèn)各種類(lèi)信息,它甚至可以你讓在運行時(shí)讀寫(xiě)屬性字段、調用所選擇的類(lèi)的方法。

反射是一個(gè)強大的工具,它讓你建立靈活能夠在運行時(shí)組裝的代碼,而不需要連接組件間的源代碼。反射的一些特征也帶來(lái)一些問(wèn)題。在這章中,我將會(huì )探究在應用程序中不打算使用反射的原因,以為什么使用它的原因。在你了解到這些利弊之后,你就會(huì )在好處大于缺點(diǎn)的時(shí)候做出決定。

初識class
使用反射的起點(diǎn)總時(shí)一個(gè)java.lang.Class類(lèi)的實(shí)例。如果你與一個(gè)預先確定的類(lèi)一同工作,Java語(yǔ)言為直接獲得Class類(lèi)的實(shí)例提供了一個(gè)簡(jiǎn)單的快捷方式。例如:
Class clas = MyClass.class;
當你使用這項技術(shù)的時(shí)候,所有與裝載類(lèi)有關(guān)的工作都發(fā)生在幕后。如果你需要在運行時(shí)從外部的資源中讀取類(lèi)名,使用上面這種方法是不會(huì )達到目的的,相反你需要使用類(lèi)裝載器來(lái)查找類(lèi)的信息,方法如下所示:
// "name" is the class name to load
Class clas = null;
try {
  clas = Class.forName(name);
} catch (ClassNotFoundException ex) {
  // handle exception case
}
// use the loaded class


如果類(lèi)已經(jīng)裝載,你將會(huì )找到當前在在的類(lèi)的信息。如果類(lèi)還沒(méi)有被裝載,那么類(lèi)裝載器將會(huì )裝載它,并且返回最近創(chuàng )建的類(lèi)的實(shí)例。

關(guān)于類(lèi)的反射

Class對象給予你了所有的用于反射訪(fǎng)問(wèn)類(lèi)的元數據的基本鉤子。這些元數據包括有關(guān)類(lèi)的自身信息,例如象類(lèi)的包和子類(lèi),還有這個(gè)類(lèi)所實(shí)現的接口,還包括這個(gè)類(lèi)所定義的構造器、屬性字段以及方法的詳細信息。后面的這些項是我們在程序設計過(guò)種經(jīng)常使用的,因此在這一節的后面我會(huì )給出一些用這些信息來(lái)工作的例子。

對于類(lèi)的構造中的每一種類(lèi)型(構造器、屬性字段、方法),java.lang.Class提供了四種獨立的反射調用以不的方式來(lái)訪(fǎng)問(wèn)類(lèi)的信息。下面列出了這四種調用的標準形式,它是一組用于查找構造器的調用。

Constructor getConstructor(Class[] params)   使用指定的參數類(lèi)型來(lái)獲得公共的構造器;
Constructor[] getConstructors()    獲得這個(gè)類(lèi)的所有構造器;
Constructor getDeclaredConstructor(Class[] params) 使用指定的參數類(lèi)型來(lái)獲得構造器(忽略訪(fǎng)問(wèn)的級別)
Constructor[] getDeclaredConstructors()  獲得這個(gè)類(lèi)的所有的構造器(忽略訪(fǎng)問(wèn)的級別)

上述的每一種方法都返回一或多個(gè)java.lang.reflect.Constructor的實(shí)例。Constructor類(lèi)定義了一個(gè)需要一個(gè)對象數據做為唯一參數的newInstance方法,然后返回一個(gè)最近創(chuàng )建的原始類(lèi)的實(shí)例。對象數組是在構造器調用時(shí)所使用的參數值。例如,假設你有一個(gè)帶有一對String 類(lèi)型做為參數的構造器的TwoString類(lèi),代碼如下所示:
public class TwoString {
    private String m_s1, m_s2;
    public TwoString(String s1, String s2) {
        m_s1 = s1;
        m_s2 = s2;
    }
}

下面的代碼顯示如何獲得TwoString類(lèi)的構造器,并使用字符串“a”和“b”來(lái)創(chuàng )建一個(gè)實(shí)例:
Class[] types = new Class[] { String.class, String.class };
    Constructor cons = TwoString.class.getConstructor(types);
    Object[] args = new Object[] { "a", "b" };
    TwoString ts = cons.newInstance(args);

上面的代碼忽略了幾種可能的被不同的反射方法拋出的異常檢查的類(lèi)型。這些異常在Javadoc API中有詳細的描述,因此為簡(jiǎn)便起見(jiàn),我會(huì )在所有的代碼中忽略它們。

在我涉及到構造器這個(gè)主題時(shí),Java語(yǔ)言也定義了一個(gè)特殊的沒(méi)有參數的(或默認)構造器快捷方法,你能使用它來(lái)創(chuàng )建一個(gè)類(lèi)的實(shí)例。這個(gè)快捷方法象下面的代碼這樣被嵌入到類(lèi)的自定義中:
Object newInstance() ?使用默認的構造器創(chuàng )建新的實(shí)例。

盡管這種方法只讓你使用一個(gè)特殊的構造器,但是如果你需要的話(huà),它是非常便利的快捷方式。這項技術(shù)在使用JavaBeans工作的時(shí)候尤其有用,因為JavaBeans需要定義一個(gè)公共的、沒(méi)有參數的構造器。

通過(guò)反射來(lái)查找屬性字段

Class類(lèi)反射調用訪(fǎng)問(wèn)屬性字段信息與那些用于訪(fǎng)問(wèn)構造器的方法類(lèi)似,在有數組類(lèi)型的參數的使用屬性字段名來(lái)替代:使用方法如下所示:
Field getField(String name)  --獲得由name指定的具有public級別的屬性字段
Field getFields() ?獲得一個(gè)類(lèi)的所有具有public級別的屬性字段
Field getDeclaredField(String name) ?獲得由name指定的被類(lèi)聲明的屬性字段
Field getDeclaredFields() ?獲得由類(lèi)定義的所有的屬性字段

盡管與構造器的調用很相似,但是在提到屬性字段的時(shí)候,有一個(gè)重要的差別:前兩個(gè)方法返回能過(guò)類(lèi)來(lái)訪(fǎng)問(wèn)的公共(public)屬性字段的信息(包括那些來(lái)自于超類(lèi)的屬性字段),后兩個(gè)方法返回由類(lèi)直接聲明的所有的屬性字段(忽略了屬性字段的訪(fǎng)問(wèn)類(lèi)型)。

Java.lang.reflect.Field的實(shí)例通過(guò)調用定義好的getXXX和setXXX方法來(lái)返回所有的原始的數據類(lèi)型,就像普通的與對象引用一起工作的get和set方法一樣。盡管getXXX方法會(huì )自動(dòng)地處理數據類(lèi)型轉換(例如使用getInt方法來(lái)獲取一個(gè)byte類(lèi)型的值),但使用一個(gè)適當基于實(shí)際的屬性字段類(lèi)型的方法是應該優(yōu)先考慮的。

下面的代碼顯示了如何使用屬性字段的反射方法,通過(guò)指定屬性字段名,找到一個(gè)對象的int類(lèi)型的屬性字段,并給這個(gè)屬性字段值加1。
public int incrementField(String name, Object obj) throws... {
    Field field = obj.getClass().getDeclaredField(name);
    int value = field.getInt(obj) + 1;
    field.setInt(obj, value);
    return value;
}

這個(gè)方法開(kāi)始展現一些使用反射所可能帶來(lái)的靈活性,它優(yōu)于與一個(gè)特定的類(lèi)一同工作,incrementField方法把要查找的類(lèi)信息的對象傳遞給getClass方法,然后直接在那個(gè)類(lèi)中查找命名的屬性字段。

通過(guò)反射來(lái)查找方法
Class反射調用訪(fǎng)問(wèn)方法的信息與訪(fǎng)問(wèn)構造器和字段屬性的方法非常相似:
    Method getMethod(String name,Class[] params)  --使用指定的參數類(lèi)型獲得由name參數指定的public類(lèi)型的方法。
Mehtod[] getMethods()?獲得一個(gè)類(lèi)的所有的public類(lèi)型的方法
Mehtod getDeclaredMethod(String name, Class[] params)?使用指定的參數類(lèi)型獲得由name參數所指定的由這個(gè)類(lèi)聲明的方法。
Method[] getDeclaredMethods() ?獲得這個(gè)類(lèi)所聲明的所有的方法

與屬性字段的調用一樣,前兩個(gè)方法返回通過(guò)這個(gè)類(lèi)的實(shí)例可以訪(fǎng)問(wèn)的public類(lèi)型的方法?包括那些繼承于超類(lèi)的方法。后兩個(gè)方法返回由這個(gè)類(lèi)直接聲明的方法的信息,而不管方法的訪(fǎng)問(wèn)類(lèi)型。

過(guò)調用返回的Java.lang.reflect.Mehtod實(shí)例定義了一個(gè)invoke方法,你可以使用它來(lái)調用定義類(lèi)的有關(guān)實(shí)例。這個(gè)invoke方法需要兩個(gè)參數,一個(gè)是提供這個(gè)方法的類(lèi)的實(shí)例,一個(gè)是調用這個(gè)方法所需要的參數值的數組。

下面給出了比屬性字段的例子更加深入的例子,它顯示了一個(gè)的方法反射的例子,這個(gè)方法使用get和set方法來(lái)給JavaBean定義的int類(lèi)型的屬性做增量操作。例如,如果對象為一個(gè)整數類(lèi)型count屬性定義了getCount和setCount方法,那么為了給這個(gè)屬性做增量運算,你就可以把“count”做為參數名傳遞給調用的這個(gè)方法中。示例代碼如下:
public int incrementProperty(String name, Object obj) {
    String prop = Character.toUpperCase(name.charAt(0)) +
        name.substring(1);
    String mname = "get" + prop;
    Class[] types = new Class[] {};
    Method method = obj.getClass().getMethod(mname, types);
    Object result = method.invoke(obj, new Object[0]);
    int value = ((Integer)result).intValue() + 1;
    mname = "set" + prop;
    types = new Class[] { int.class };
    method = obj.getClass().getMethod(mname, types);
    method.invoke(obj, new Object[] { new Integer(value) });
    return value;
}

根據JavaBeans的規范,我把屬性名的第一個(gè)字母轉換為大寫(xiě),然后在前面加上“get”來(lái)建立讀取屬性值的方法名,在屬性名前加上“set”來(lái)建立設置屬性值的方法名。JavaBeans的讀方法只返回屬性值,寫(xiě)方法只需要要寫(xiě)入的值做為參數,因此我指定了與這個(gè)方法相匹配的參數類(lèi)型。最后規范規定這兩個(gè)方法應該是public類(lèi)型的,因此我使用了查找相關(guān)類(lèi)的public類(lèi)型方法的調用形式。

這個(gè)例子我首先使用反射傳遞一個(gè)原始類(lèi)型的值,因此讓我們來(lái)看一下它是怎樣工作的?;镜脑硎呛?jiǎn)單的:無(wú)論什么時(shí)候,你需要傳遞一個(gè)原始類(lèi)型的值,你只要替換相應的封裝原始類(lèi)型的(在java.lang 包中定義的)的類(lèi)的實(shí)例就可以了。這種方法可應用于調用和返回。因此在我的例子中調用get方法時(shí),我預期的結果是一個(gè)由java.lang.Integer類(lèi)所封裝的實(shí)際的int類(lèi)型的屬性值。

反射數組

在Java語(yǔ)言中數組是對象,象其它所有的對象一樣,它有一些類(lèi)。如果你有一個(gè)數組,你可以和其它任何對象一樣使用標準的getClass方法來(lái)獲得這個(gè)數組的類(lèi),但是你獲得的這個(gè)類(lèi)與其它的對象類(lèi)型相比,不同之處在它沒(méi)有一個(gè)現存的工作實(shí)例。即使你有了一個(gè)數組類(lèi)之后,你也不能夠直接用它來(lái)做任何事情,因為通過(guò)反射為普通的類(lèi)所提供的構造器訪(fǎng)問(wèn)不能為數組工作,并且數組沒(méi)有任何可訪(fǎng)問(wèn)的屬性字段,只有基本的為數組對象定義的java.lang.Object類(lèi)型的方法。

數組特殊處理要使用java.lang.reflect.Array類(lèi)提供的一個(gè)靜態(tài)方法的集合,這個(gè)類(lèi)中的方法可以讓你創(chuàng )建新的數組,獲得一個(gè)數組對象的長(cháng)度,以及讀寫(xiě)一個(gè)數組對象的索引值。

下面的代碼顯示了有效調整一個(gè)現存數組的尺寸的方法。它使用反射來(lái)創(chuàng )建一個(gè)相同類(lèi)型的新數組,然后在返回這個(gè)新數組之前把原數組中的所有的數據復制到新的數組中。
public Object growArray(Object array, int size) {
    Class type = array.getClass().getComponentType();//得到數組類(lèi)
    Object grown = Array.newInstance(type, size);//得到數組的實(shí)例
    System.arraycopy(array, 0, grown, 0,
        Math.min(Array.getLength(array), size));
    return grown;
}

安全與反射

在處理反射的時(shí)候,安全是一個(gè)復雜的問(wèn)題。反射正常被框架類(lèi)型的代碼使用,并因為這樣,你可能會(huì )經(jīng)常要求框架不關(guān)心普通的訪(fǎng)問(wèn)限制來(lái)完全訪(fǎng)問(wèn)你的代碼。然而,自由的訪(fǎng)問(wèn)可能會(huì )在其它的一些實(shí)例中產(chǎn)生一些風(fēng)險,例如在代碼在一個(gè)不被信任的代碼共享環(huán)境中被執行的時(shí)候。

因為這些沖突的需要,Java語(yǔ)言定義了一個(gè)多級方法來(lái)處理反射安全?;镜哪J绞窃诜瓷湔埱笤创a訪(fǎng)問(wèn)的時(shí)候強制使用如下相同的約束限制:
訪(fǎng)問(wèn)這個(gè)類(lèi)中來(lái)自任何地方的public組件;
不訪(fǎng)問(wèn)這個(gè)類(lèi)本身外部的private組件;
限制訪(fǎng)問(wèn)protected和package(默認訪(fǎng)問(wèn))組件。

繞這些限制有一個(gè)簡(jiǎn)單的方法,我在前面的例子中所使用的所有構造器、屬性字段、以及類(lèi)的方法都擴展于一個(gè)共同的基類(lèi)???java.lang.reflect.AccessibleObject類(lèi)。這個(gè)類(lèi)定義了一個(gè)setAccessible方法,這個(gè)方法可以讓你打開(kāi)或關(guān)閉這些對類(lèi)的實(shí)例的訪(fǎng)問(wèn)檢查。如果安全管理器被設置為關(guān)閉訪(fǎng)問(wèn)檢查,那么就允許你訪(fǎng)問(wèn),否則不允許,安全管理器會(huì )拋出一個(gè)異常。

下面是一個(gè)使用反向來(lái)演示這種行為的TwoString類(lèi)的實(shí)例。
public class ReflectSecurity {
    public static void main(String[] args) {
        try {
            TwoString ts = new TwoString("a", "b");
            Field field = clas.getDeclaredField("m_s1");
//          field.setAccessible(true);
            System.out.println("Retrieved value is " +
                field.get(inst));
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }
}

如果你編譯這段代碼并且直接使用不帶任何參數的命令行命令來(lái)運行這個(gè)程序,它會(huì )拋出一個(gè)關(guān)于field.get(inst)調用的IllegalAccessException異常,如果你去掉上面代碼中field.setAccessible(true)行的注釋?zhuān)缓缶幾g并重新運行代碼,它就會(huì )成功執行。最后,如果你在命令行給JVM添加一個(gè)Djava.security.manager參數,使得安全管理器可用,那么它又會(huì )失敗,除非你為ReflectSecurity類(lèi)定義安全許可。

反射性能
反射是一個(gè)強大的工具,但是也會(huì )帶一些缺點(diǎn)。主要缺點(diǎn)之一就是對性能的影響。使用反射是基本的解釋性操作,你告訴JVM你要做什么,它就會(huì )為你做什么。這種操作類(lèi)型總是比直接做同樣的操作要慢。為了演示使用反射所要付出的性能代價(jià),我為這篇文章準備了一套基準程序(可以從資源中下載)。

下面列出一段來(lái)自于屬性字段的訪(fǎng)問(wèn)性能測試的摘要,它包括基本的測試方法。每個(gè)方法測試一種訪(fǎng)問(wèn)屬性字段的形式,accessSame方法和本對象的成員字段一起工作,accessReference方法直接使用另外的對象屬性字段來(lái)存取,accessReflection通過(guò)反射使用另一個(gè)對象的屬性字段來(lái)存取,每個(gè)方法都使用相同的計算???在循環(huán)中簡(jiǎn)單的加/乘運算。
public int accessSame(int loops) {
    m_value = 0;
    for (int index = 0; index < loops; index++) {
        m_value = (m_value + ADDITIVE_VALUE) *
            MULTIPLIER_VALUE;
    }
    return m_value;
}

public int accessReference(int loops) {
    TimingClass timing = new TimingClass();
    for (int index = 0; index < loops; index++) {
        timing.m_value = (timing.m_value + ADDITIVE_VALUE) *
            MULTIPLIER_VALUE;
    }
    return timing.m_value;
}

public int accessReflection(int loops) throws Exception {
    TimingClass timing = new TimingClass();
    try {
        Field field = TimingClass.class.
            getDeclaredField("m_value");
        for (int index = 0; index < loops; index++) {
            int value = (field.getInt(timing) +
                ADDITIVE_VALUE) * MULTIPLIER_VALUE;
            field.setInt(timing, value);
        }
        return timing.m_value;
    } catch (Exception ex) {
        System.out.println("Error using reflection");
        throw ex;
    }
}

測試程序在一個(gè)大循環(huán)中反復的調用每個(gè)方法,在調用結束后計算平均時(shí)間。每個(gè)方法的第一次調用不包括在平均值中,因些初始化時(shí)間不是影響結果的因素。為這篇文章所做的測試運行,我為每個(gè)調用使用了10000000的循環(huán)計數,代碼運行在1GHz PIII系統上。并且分別使用了三個(gè)不同的LinuxJVM,對于每個(gè)JVM都使用了默認設置,測試結果如下圖所示:
 

上面的圖表的刻度可以顯示整個(gè)測試范圍,但是那樣的話(huà)就會(huì )減少差別的顯示效果。這個(gè)圖表中的前兩個(gè)是用SUN的JVM的進(jìn)行測試的結果圖,使用反射的執行時(shí)間比使用直接訪(fǎng)問(wèn)的時(shí)間要超過(guò)1000多倍。最后一個(gè)圖是用IBM的JVM所做的測試,通過(guò)比較要SUN的JVM執行效率要高一些,但是使用反射的方法依然要比其它方法超出700多倍。雖然IBM的JVM要比SUN的JVM幾乎要快兩倍,但是在使用反射之外的兩種方法之間,對于任何的JVM在執行效率上沒(méi)有太大的差別。最大的可能是,這種差別反映了通過(guò)Sun Hot Spot JVMs在簡(jiǎn)化基準方面所做的專(zhuān)門(mén)優(yōu)化很少。

除了屬性字段訪(fǎng)問(wèn)時(shí)間的測試以外,我對方法做了同樣的測試。對于方法的調用,我償試了與屬性字段訪(fǎng)問(wèn)測試一樣的三種方式,用額外使用了沒(méi)有參數的方法的變量與傳遞并返回一個(gè)值的方法調用相對比。下面的代碼顯示了使用傳遞并返回值的調用方式進(jìn)行測試的三種方法。
public int callDirectArgs(int loops) {
    int value = 0;
    for (int index = 0; index < loops; index++) {
        value = step(value);
    }
    return value;
}

public int callReferenceArgs(int loops) {
    TimingClass timing = new TimingClass();
    int value = 0;
    for (int index = 0; index < loops; index++) {
        value = timing.step(value);
    }
    return value;
}

public int callReflectArgs(int loops) throws Exception {
    TimingClass timing = new TimingClass();
    try {
        Method method = TimingClass.class.getMethod
            ("step", new Class [] { int.class });
        Object[] args = new Object[1];
        Object value = new Integer(0);
        for (int index = 0; index < loops; index++) {
            args[0] = value;
            value = method.invoke(timing, args);
        }
        return ((Integer)value).intValue();
    } catch (Exception ex) {
        System.out.println("Error using reflection");
        throw ex;
    }
}

下圖顯示我使用這些方法的測試結果,這里再一次顯示了反射要比其它的直接訪(fǎng)問(wèn)要慢很多。雖然對于無(wú)參數的案例,執行效率從SUN1.3.1JVM的慢幾百倍到IBM的JVM慢不到30倍,與屬性字段訪(fǎng)問(wèn)案例相比,差別不是很大,這種情況的部分原因是因為java.lang.Integer的包裝器需要傳遞和返回int類(lèi)型的值。因為Intergers是不變的,因此就需要為每個(gè)方法的返回生成一個(gè)新值,這就增加了相當大的系統開(kāi)銷(xiāo)。

 

反射的性能是SUN在開(kāi)發(fā)1.4JVM時(shí)重點(diǎn)關(guān)注的一個(gè)領(lǐng)域,從上圖可以看到改善的結果。Sun1.4.1JVM對于這種類(lèi)型的操作比1.3.1版有了很大的提高,要我的測試中要快大約7倍。IBM的1.4.0JVM對于這種測試提供了更好的性能,它的運行效率要比Sun1.4.1JVM快兩到三倍。

我還為使用反射創(chuàng )建對象編寫(xiě)了一個(gè)類(lèi)似的效率測試程序。雖然這個(gè)例子與屬性字段和方法調用相比差別不是很大,但是在Sun1.3.1JVM上調用newInstance()方法創(chuàng )建一個(gè)簡(jiǎn)單的java.lang.Object大約比直接使用new Object()方法長(cháng)12倍的時(shí)間,在IBM1.4.0JVM上大約要長(cháng)4倍的時(shí)間,在Sun1.4.1JVM上大約要長(cháng)2倍的時(shí)間。對于任何用于測試的JVM,使用Array.newInstance(Type,size)方法創(chuàng )建一個(gè)數組所需要的時(shí)間比使用new tye[size]所花費的時(shí)間大約要長(cháng)兩倍,隨著(zhù)數組民尺寸的增長(cháng),這兩種方法的差別的將隨之減少。

反射概要總結

Java 語(yǔ)言的反射機制提供了一種非常通用的動(dòng)態(tài)連接程序組件的方法。它允許你的程序創(chuàng )建和維護任何類(lèi)的對象(服從安全限制),而不需要提前對目標類(lèi)進(jìn)行硬編碼。這些特征使得反射在創(chuàng )建與對象一同工作的類(lèi)庫中的通用方法方面非常有用。例如,反射經(jīng)常被用于那些數據庫,XML、或者其它的外部的持久化對象的框架中。

反射還有兩個(gè)缺點(diǎn),一個(gè)是性能問(wèn)題。在使用屬性字段和方法訪(fǎng)問(wèn)的時(shí)候,反射要比直接的代碼訪(fǎng)問(wèn)要慢很多。至于對影響的程度,依賴(lài)于在程序中怎樣使用反射。如果它被用作一個(gè)相關(guān)的很少發(fā)生的程序操作中,那么就不必關(guān)心降低的性能,即使在我的測試中所展示的最耗時(shí)的反射操作的圖形中也只是幾微秒的時(shí)間。如果要在執行應用程序的核心邏輯中使用反射,性能問(wèn)題才成為一個(gè)要嚴肅對象的問(wèn)題。

對于很多應用中的存在的缺點(diǎn)是使用反射可以使你的實(shí)際的代碼內部邏輯變得模糊不清。程序員都希望在源代碼中看到一個(gè)程序的邏輯以及象繞過(guò)源代碼的反射所可能產(chǎn)生的維護問(wèn)題這樣的一些技術(shù)。反射代碼也比相應的直接代碼要復雜一些,就像在性能比較的代碼實(shí)例看到那樣。處理這些問(wèn)題的最好方法是盡可能少使用反射,只有在一些增加靈活性的地方來(lái)使用它。

在下一篇文章中,我將給出一個(gè)更加詳細的如何使用反射的例子。這個(gè)例子提供了一個(gè)用于處理傳遞給一個(gè)Java應用程序的命令行參數的API。在避免弱點(diǎn)的同時(shí),它也顯示了反射的強大的功能,反射能夠使用的你的命令處理變得的簡(jiǎn)單嗎?你可以在Java 動(dòng)態(tài)程序設計的第三部分中找到答案。


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=450623

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
反射,java的靈魂
Java類(lèi)文件的基本結構
java jvm字節占用空間分析
通往高級 Java 開(kāi)發(fā)的必經(jīng)之路(下)
《深入理解JVM(5)——虛擬機類(lèi)加載機制》
java拾遺4--一個(gè)簡(jiǎn)單java程序的運行全過(guò)程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久