天天看點

JAVA語言中的反射機制:

在Java 運作時 環境中,對于任意一個類,能否知道這個類有哪些屬性和方法? 對于任意一個對象,能否調用他的方法?這些答案是肯定的,這種動态擷取類的資訊,以及動态調用類的方法的功能來源于JAVA的反射。進而使java具有動态語言的特性。 JAVA反射機制主要提供了以下功能: 1.在運作時判斷任意一個對象所屬的類 2.在運作時構造任意一個類的對象 3.在運作時判斷任意一個類所具有的成員變量和方法(通過反射甚至可以調用private方法) 4.在運作時調用任意一個對象的方法(*****注意:前提都是在運作時,而不是在編譯時) Java 反射相關的API簡介: 位于java。lang。reflect包中 --Class類:代表一個類 --Filed類:代表類的成員變量 --Method類:代表類的方法 --Constructor類:代表類的構造方法 --Array類:提供了動态建立數組,以及通路數組的元素的靜态方法。該類中的所有方法都是靜态方法 ----Class類 在 java 的Object類中的申明了數個應該在所有的java類中被改寫的methods: hashCode(), equals(),clone(),toString(),getClass()等,其中的getClass()傳回yige Class 類型的對象。 Class類十分的特殊,它和一般的類一樣繼承自Object,其實體用以表達java程式運作 時的 class和 interface,也用來表達 enum,array,primitive,Java Types 以及關鍵字void ,當加載一個類,或者當加載器(class loader)的defineClass()被JVM調用,便産生一個Class 對象, Class是Reflection起源,針對任何你想探勘的class(類),唯有現為他産生一個Class 的對象,接下來才能經由後者喚起為數十多個的反射API。 Java允許我們從多種途徑為一個類class生成對應的Class對象。 --運用 getClass():Object類中的方法,每個類都擁有此方法 String str="abc"; Class cl=str.getClass(); --運用 Class。getSuperclass():Class類中的方法,傳回該Class的父類的Class --運用 Class。forName()靜态方法: --運用 ,Class:類名.class --運用primitive wrapper classes的TYPE文法: 基本類型包裝類的TYPE,如:Integer.TYPE 注意:TYPE的使用,隻适合原生(基本)資料類型 ----運作時生成instance 想生成對象的實體,在反射動态機制中有兩種方法,一個針對無變量的構造方法,一個針對帶參數的 構造方法,,如果想調用帶參數的構造方法,就比較的麻煩,不能直接調用Class類中的newInstance() ,而是調用Constructor類中newInstance()方法,首先準備一個Class[]作為Constructor的參數類型。 然後調用該Class對象的getConstructor()方法獲得一個專屬的Constructor的對象,最後再準備一個 Object[]作為Constructor對象昂的newInstance()方法的實參。 在這裡需要說明的是 隻有兩個類擁有newInstance()方法,分别是Class類和Constructor類 Class類中的newInstance()方法是不帶參數的,而Constructro類中的newInstance()方法是帶參數的 需要提供必要的參數。 例: Class c=Class.forName("DynTest"); Class[] ptype=new Class[]{double.class,int.class}; Constructor ctor=c.getConstructor(ptypr); Object[] obj=new Object[]{new Double(3.1415),new Integer(123)}; Object object=ctor.newInstance(obj); System.out.println(object); ----運作時調用Method 這個動作首先準備一個Class[]{}作為getMethod(String name,Class[])方法的參數類型,接下來準備一個 Obeject[]放置自變量,然後調用Method對象的invoke(Object obj,Object[])方法。 注意,在這裡調用 ----運作時調用Field内容 變更Field不需要參數和自變量,首先調用Class的getField()并指定field名稱,獲得特定的Field對象後 便可以直接調用Field的 get(Object obj)和set(Object obj,Object value)方法 來源:http://www.javaeye.com/topic/136205