java的反射機制

1、java的反射機制淺談java

 

最近研究java研究得很給力,主要以看博文爲學習方式。如下是我對java的反射機制所產生的一些感悟,但願各位童鞋看到失誤之處不吝指出。受到各位指教之處,如若讓小生好好感動,說不定會請各位吃飯哦!數組

 

1.何謂反射機制jvm

 

根據網文,java中的反射機制能夠如此定義:函數

JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。學習

 

2.反射機制如何實現spa

 

談到反射機制,最誘人的莫過於「動態」二字了。接觸過C語言的童鞋們都知道,C語言中也有個和「動態」搭上邊的函數:malloc()函數。其實這裏的兩個動態是一個意思,都指的是非編譯時處理,抑或運行時處理。這種機制,可讓程序的彈性增長很多,由於藉由此機制,客戶能夠在程序運行時改變一些他關心的性質:分配內存(固然他可能 徹底不知道這麼作了),調用某個類(固然他仍是被矇在鼓裏)等。code

下面咱們就聊聊java中動態機制是如何實現的。對象

 

上一篇文章中提到了java的類的加載問題,但沒有更深刻地解釋其運行機制,在這裏就先談談這個問題。索引

 

首先不得不提到的是java.lang.Class這個類。內存

有這麼一段話:

Java程序在運行時,Java運行時系統一直對全部的對象進行所謂的運行時類型標識。這項信息紀錄了每一個對象所屬的類。虛擬機一般使用運行時類型信息選準正確方法去執行,用來保存這些類型信息的類是Class類。

 

也就是說,ClassLoader找到了須要調用的類時(java爲了調控內存的調用消耗,類的加載都在須要時再進行,很摳可是頗有效),就會加載它,而後根據.class文件內記載的類信息來產生一個與該類相聯繫的獨一無二的Class對象。該Class對象記載了該類的字段,方法等等信息。之後jvm要產生該類的實例,就是根據內存中存在的該Class類所記載的信息(Class對象應該和我所瞭解的其餘類同樣會在堆內存內產生、消亡)來進行。

 

而java中的Class類對象是能夠人工天然性的(也就是說開放的)獲得的(雖然你沒法像其餘類同樣運用構造器來獲得它的實例,由於

Class對象都是jvm產生的。不過話說回來,客戶產生的話也是無心義的),並且,更偉大的是,基於這個基礎,java實現了反射機制。

 

獲取Class對象有三種方式:

 

1.經過Object類的getClass()方法。例如:

Class c1 = new String("").getClass();

2.經過Class類的靜態方法——forName()來實現:

Class c2 = Class.forName("MyObject");

3.若是T是一個已定義的類型的話,在java中,它的.class文件名:T.class就表明了與其匹配的Class對象,例如:

Class c3 = Manager.class;
Class c4 = int.class;
Class c5 = Double[].class;

這裏須要解釋一下3:請記住一句話,java中,一切皆對象。也就是說,基本類型int float 等也會在jvm的內存池像其餘類型同樣中生成

一個Class對象。而數組等組合型數據類型也是會生成一個Class對象的,並且更使人驚訝的是,java中數組的原本面目其實就是某個類,驚訝

中的驚訝是,含有相同元素的相同維數的數組還會共同享用同一個Class對象!其實根據個人臆想,數組的length性質應該就保存在這個Class

對象裏面。

 

Class類中存在如下幾個重要的方法:

 

1.getName()

一個Class對象描述了一個特定類的特定屬性,而這個方法就是返回String形式的該類的簡要描述。因爲歷史緣由,對數組的Class對象

調用該方法會產生奇怪的結果。


2.newInstance()

該方法能夠根據某個Class對象產生其對應類的實例。須要強調的是,它調用的是此類的默認構造方法。例如:

MyObject x = new MyObject();
MyObject y = x.getClass().newInstance();

3.getClassLoader()

返回該Class對象對應的類的類加載器。

 

4.getComponentType()

該方法針對數組對象的Class對象,能夠獲得該數組的組成元素所對應對象的Class對象。例如:

int[] ints = new int[]{1,2,3};
Class class1 = ints.getClass();
Class class2 = class1.getComponentType();

而這裏獲得的class2對象所對應的就應該是int這個基本類型的Class對象。

 

5.getSuperClass()

返回某子類所對應的直接父類所對應的Class對象。

 

6.isArray()

斷定此Class對象所對應的是不是一個數組對象。

 

好啦,如今對Class這個類應該有了一個大體的瞭解,下面就給出一個反射機制的典型例子供各位分析:

import java.lang.reflect.Array;   
import java.lang.reflect.Constructor;   
import java.lang.reflect.Field;   
import java.lang.reflect.Method;   
  
  
/**  
 * Java Reflection Cookbook  
 *  
 * @author Michael Lee  
 * @since 2006-8-23  
 * @version 0.1a  
 */  
  
public class Reflection {   
    /**  
     * 獲得某個對象的公共屬性  
     *  
     * @param owner, fieldName  
     * @return 該屬性對象  
     * @throws Exception  
     *  
     */  
    public Object getProperty(Object owner, String fieldName) throws Exception {   
        Class ownerClass = owner.getClass();   
  
        Field field = ownerClass.getField(fieldName);   
  
        Object property = field.get(owner);   
  
        return property;   
    }   
  
    /**  
     * 獲得某類的靜態公共屬性  
     *  
     * @param className   類名  
     * @param fieldName   屬性名  
     * @return 該屬性對象  
     * @throws Exception  
     */  
    public Object getStaticProperty(String className, String fieldName)   
            throws Exception {   
        Class ownerClass = Class.forName(className);   
  
        Field field = ownerClass.getField(fieldName);   
  
        Object property = field.get(ownerClass);   
  
        return property;   
    }   
  
  
    /**  
     * 執行某對象方法  
     *  
     * @param owner  
     *            對象  
     * @param methodName  
     *            方法名  
     * @param args  
     *            參數  
     * @return 方法返回值  
     * @throws Exception  
     */  
    public Object invokeMethod(Object owner, String methodName, Object[] args)   
            throws Exception {   
  
        Class ownerClass = owner.getClass();   
  
        Class[] argsClass = new Class[args.length];   
  
        for (int i = 0, j = args.length; i < j; i++) {   
            argsClass[i] = args[i].getClass();   
        }   
  
        Method method = ownerClass.getMethod(methodName, argsClass);   
  
        return method.invoke(owner, args);   
    }   
  
  
      /**  
     * 執行某類的靜態方法  
     *  
     * @param className  
     *            類名  
     * @param methodName  
     *            方法名  
     * @param args  
     *            參數數組  
     * @return 執行方法返回的結果  
     * @throws Exception  
     */  
    public Object invokeStaticMethod(String className, String methodName,   
            Object[] args) throws Exception {   
        Class ownerClass = Class.forName(className);   
  
        Class[] argsClass = new Class[args.length];   
  
        for (int i = 0, j = args.length; i < j; i++) {   
            argsClass[i] = args[i].getClass();   
        }   
  
        Method method = ownerClass.getMethod(methodName, argsClass);   
  
        return method.invoke(null, args);   
    }   
  
  
  
    /**  
     * 新建實例  
     *  
     * @param className  
     *            類名  
     * @param args  
     *            構造函數的參數  
     * @return 新建的實例  
     * @throws Exception  
     */  
    public Object newInstance(String className, Object[] args) throws Exception {   
        Class newoneClass = Class.forName(className);   
  
        Class[] argsClass = new Class[args.length];   
  
        for (int i = 0, j = args.length; i < j; i++) {   
            argsClass[i] = args[i].getClass();   
        }   
  
        Constructor cons = newoneClass.getConstructor(argsClass);   
  
        return cons.newInstance(args);   
  
    }   
  
  
       
    /**  
     * 是否是某個類的實例  
     * @param obj 實例  
     * @param cls 類  
     * @return 若是 obj 是此類的實例,則返回 true  
     */  
    public boolean isInstance(Object obj, Class cls) {   
        return cls.isInstance(obj);   
    }   
       
    /**  
     * 獲得數組中的某個元素  
     * @param array 數組  
     * @param index 索引  
     * @return 返回指定數組對象中索引組件的值  
     */  
    public Object getByArray(Object array, int index) {   
        return Array.get(array,index);   
    }   
}
相關文章
相關標籤/搜索