java 反射的學習


基本概念

  在Java運行時環境中,對於任意一個類,能否知道這個類有哪些屬性和方法?對於任意一個對象,能否調用它的任意一個方法?

  答案是肯定的。

  這種動態獲取類的信息以及動態調用對象的方法的功能來自於Java語言的反射(Reflection)機制

JAVA反射機制是指:在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法;這種動態獲取的以及動態調用對象的方法的功能稱爲java語言的反射機制。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。 

  Java反射機制主要提供了以下功能:

  1.在運行時判斷任意一個對象所屬的類。

  2.在運行時構造任意一個類的對象。

  3.在運行時判斷任意一個類所具有的成員變量和方法。

  4.在運行時調用任意一個對象的方法。

 

  Reflection是Java被視爲動態(或準動態)語言的一個關鍵性質。

  這個機制允許程序在運行時透過Reflection APIs取得任何一個已知名稱的class的內部信息。

  包括其modifiers(諸如public、static等)、 superclass(例如Object)、實現了的 interfaces (例如Serializable)、也包括其fields和methods的所有信息,並可於運行時改變fields內容或調用methods。

 

動態語言

  動態語言的定義“程序運行時,允許改變程序結構或者變量類型,這種語言稱爲動態語言”。

  從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。

  儘管在這樣的定義與分類下Java不是動態語言,它卻有着一個非常突出的動態相關機制:Reflection。這個字的意思是:反射、映像、倒影,用在Java身上指的是我們可以於運行時加載、探知、使用編譯期間完全未知的classes。

  換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。

  這種“看透”class的能力(the ability of the program to examine itself)被稱爲introspection(內省、內觀、反省)。Reflectionintrospection是常被並提的兩個術語。

 

Java Reflection API簡介

  在JDK中,主要由以下類來實現Java反射機制,這些類(除了第一個)都位於java.lang.reflect包中

  Class類:代表一個類,位於java.lang包下。

  Field類:代表類的成員變量(成員變量也稱爲類的屬性)。

  Method類:代表類的方法。

  Constructor類:代表類的構造方法。

  Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法。


java反射機制的實現主要由三個類來主導:它們分別是Class、Field、Method;

  1. Class:

     java在編譯和運行時,會將需要被編譯和運行的所有類加載進類加載器,每個類被加載之後,系統就會爲該類生成一個對應的Class對象,通過該Class對象就可以訪問到java虛擬機中的這個類,進而在運行時對這個被訪問的類進行信息的獲取和處理(當然,不管被訪問的這個類裏的信息是否私有的);通俗的講,Class對象間接代表了它對應的類,通過這個Class對象,我們就可以大刀闊斧地去執行反射機制的實現;

       獲取Class對象主要有三種方式:

       1). 調用Class類的forName(String name)靜態方法,參數name爲Class對應的類的全名(包括包名);

           比如我們要創建Gesture這個類對應的Class對象:Class<Gesture> mClass = Class.forName("android.gesture.Gesture");

           android.gesture爲Gesture的包名,Class<Gesture>中的Gesture表示得到的是Gesture類型對應的Class對象,<>中的Gesture也可爲通配符?表示,如:Class<?>mClass = Class.forName("android.gesture.Gesture");

       2). 調用類的class屬性得到類對應的Class對象。如:Class<?>mClass = Gesture.class; (一般建議用這種方式得到Class對象)

       3).調用類的實例化對象的getClass()方法。特別說明的是,getClass()是java類的始祖Object類的方法,所以,所有java對象都可以調用該方法;如mGesture是Gesture類型的對象,Class<?> mClass = mGesture.getClass()得到的是Gesture類對應的Class對象

    那麼在得到對應類的Class對象對應後,我們就可以通過該Class對象得到它所對應的類的一些信息,比如該類的構造函數、成員(屬性)、方法(函數);

       Class類提供的相關接口介紹:(注:在表中,Class對象對應的類,姑且稱爲目標類)

接口 返回類型 接口功能實現
getPackage()
Package 得到目標類的包名對應的Package對象
getCanonicalName()
String 得到目標類的全名(包名+類名)
getName() String 同getCanonicalName()
getClassLoader()
ClassLoader
得到加載目標類的ClassLoader對象
getClasses()
Class<?>[] 得到目標類中的所有的public內部類以及public內部接口所對應的Class對象
getDeclaredClasses()
Class<?>[]
同getClasses(),但不侷限於public修飾,只要是目標類中聲明的內部類和接口均可
getConstructors()
Constructor<?>[]
得到目標類的所有public構造函數對應的Constructor對象
getDeclaredConstructors()
Constructor<?>[]
同getConstructors(),但不侷限於public修飾,只要是目標類中聲明的構造函數均可
getField(String arg)
Field 得到目標類中指定的某個public屬性對應的Field對象
getDeclaredField(String arg)
Field 同getField,但不侷限於public修飾,只要是目標類中聲明的屬性均可
getFields()
Field[] 得到目標類中所有的public屬性對應的Field對象
getDeclaredFields()
Field[] 同getFields(),但不侷限於public修飾的屬性
getMethod(String arg0, Class<?>... arg1)
method 得到目標類中指定的某個public方法對應的Method對象
getDeclaredMethod(String arg0, Class<?>... arg1)
Method 同getMethod,但不侷限於public修飾的方法
getMethods()
Method[] 得到目標類中所有的public方法對應的Method對象
getDeclaredMethods()
Method[] 同getMethods(),但不侷限於public修飾的方法
getEnclosingClass()
Class 得到目標類所在的外圍類的Class對象
getGenericInterfaces()
Type[] 得到目標類實現的接口對應的Type對象
getGenericSuperclass()
Type 得到目標類繼承的父類所對應的Type對象
getInterfaces()
Class<?>[] 得到目標類實現的接口所對應的Class對象
getSuperclass()
Class 得到目標類繼承的父類所對應的Class對象
isMemberClass()
boolean 目標類是否爲成員類
cisAnonymousClass()
boolean 目標類是否爲匿名類

   2.Field:

     我們知道一般類裏包含有屬性(成員)和方法(函數),竟然Class是描述類的信息,那麼類其它部分應該會對應有描述它們的東東,而Field類型的對象就是描述Class對象對應類的出現包括public、protected、private屬性);一個Field對象對應描述一個類的屬性;

    通過上文對Class的介紹,我們知道Class提供了四種接口函數可以得到對應屬性的Field:

     1). getField(String name):返回類型爲Field,name爲類中的屬性名,得到的是描述類中的一個public屬性對應的Field對象;如Field mField =mClass.getField("mGestureID") 得到的是Gesture類中的一個public屬性mGestureID對應的Field對象;

    2). getFields():返回類型爲Field類型數組,得到的是描述類中的所有public屬性對應的所有Field對象;

    3). getDeclaredField(String name):同getField(String name),只不過得到的Field對象描述的不只是public屬性,

        還包括protected、private屬性,也是說只要是在類中聲明的屬性;

    4). getDeclaredFields():getFields(),得到的是描述類中聲明的所有屬性(public、protected、private)對應的Field對象;

    Field類的相關函數接口介紹:

  Field類提供的相關接口介紹:(注:在表中,Field對象對應的屬性,姑且稱爲目標屬性)

接口 返回類型 接口功能實現
setAccessible(boolean flag) void 參數爲true,只要是在類中聲明的目標屬性均可訪問,爲false,只有public目標屬性可訪問
set(Object object, Object value) void 給目標屬性設置值(private、protected屬性均不能訪問,但可以通過先調用setAccessible(true)實現訪問),第一個參數爲目標屬性所在類的對象,第二個參數爲傳入的值
get(Object object) Object 得到目標屬性的值(private、protected屬性均不能訪問,但可以通過調用setAccessible(true)實現訪問),參數爲目標屬性所在類的對象
setBoolean(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲boolean
getBoolean(Object object) boolean 同get(Object object),只不過得到的數據類型爲boolean
setByte(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲byte
getByte(Object object) byte 同get(Object object),只不過得到的數據類型爲byte
setShort(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲short
getShort(Object object) short 同get(Object object),只不過得到的數據類型爲short
setInt(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲int
getInt(Object object) int 同get(Object object),只不過得到的數據類型爲int
setLong(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲long
getLong(Object object) long 同get(Object object),只不過得到的數據類型爲long
setFloat(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲float
getFloat(Object object) float 同get(Object object),只不過得到的數據類型爲float
setDouble(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲double
getDouble(Object object) double 同get(Object object),只不過得到的數據類型爲double
setChar(Object object, boolean value) void 同set(Object object, Object value),只不過操作的數據類型爲char
getChar(Object object) char 同get(Object object),只不過得到的數據類型爲char
getName() String 得到目標屬性的名字,不侷限於private修飾符,只要是類中聲明的屬性
getGenericType() Type 得到目標屬性的類型,不侷限於private修飾符
getType() Class<?> 得到目標屬性的類型對應的Class對象
getModifiers() int 得到目標屬性的修飾符值(private爲2、protected爲4、public爲1、static爲8、final爲16)
getDeclaringClass() Class<?> 得到目標屬性所在類對應的Class對象

  下面就以一個示例代碼來驗證Field表中的函數接口的實現,如下:

     1). FieldBeReflected.java(被反射的類)

[java] view plaincopy
  1. package com.stevenhu.field;  
  2.   
  3. public class FieldBeReflected   
  4. {  
  5.     private static String name;   
  6.     private static String name1;   
  7.     private boolean mBoolean = true;  
  8.     private final byte mByte = 111;  
  9.     private static final short mShort = 22;  
  10.     protected static int mInt;    
  11.     protected static long mLong;  
  12.     protected static float mFloat;  
  13.     protected static double mDouble;  
  14.     public static char mChar;  
  15.       
  16. }  

   2). ReflectField.java(執行反射調用的類)

[java] view plaincopy
  1. package com.stevenhu.reflection.test;  
  2. import java.lang.reflect.Field;  
  3. import java.lang.reflect.InvocationTargetException;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Type;  
  6.   
  7. import com.stevenhu.field.FieldBeReflected;  
  8.   
  9. public class ReflectField   
  10. {  
  11.   
  12.     public static void main(String[] args)   
  13.     {  
  14.         /*1.Class<?> clazz = Class.forName("com.stevenhu.field.FieldBeReflected"); 
  15.          *2.FieldBeReflected mFieldBeReflected = new FieldBeReflected(); 
  16.          *  Class<?> clazz = mFieldBeReflected.getClass(); 
  17.          */  
  18.         Class<?> clazz = FieldBeReflected.class;  
  19.           
  20.         try {  
  21.             Field fName = clazz.getDeclaredField("name");  
  22.             Field fBoolean = clazz.getDeclaredField("mBoolean");  
  23.             Field fByte = clazz.getDeclaredField("mByte");  
  24.             Field fShort = clazz.getDeclaredField("mShort");  
  25.             Field fInt = clazz.getDeclaredField("mInt");  
  26.             Field fLong = clazz.getDeclaredField("mLong");  
  27.             Field fFloat = clazz.getDeclaredField("mFloat");  
  28.             Field fDouble = clazz.getDeclaredField("mDouble");  
  29.             Field fChar = clazz.getDeclaredField("mChar");  
  30.       
  31.             /* 
  32.              * 參數爲true,只要是在類中聲明的目標屬性均可訪問, 
  33.              * 爲false,則被反射類和反射類在同一個包中時,private目標屬性不可訪問, 
  34.              * 不在同一個包中時,private、protected目標屬性均不可訪問 
  35.              */  
  36.             fName.setAccessible(true);  
  37.               
  38.             /*給目標屬性設置值(private屬性不能訪問,但可以通過先調用setAccessible(true)實現訪問), 
  39.              * 由於ReflectField類中的name屬性是靜態的(static),所以方法的第一個實參傳入的是 
  40.              * 目標屬性所在類對應的Class對象clazz,也可以是類的實例clazz.newInstance(); 
  41.              */  
  42.             fName.set(clazz, "reflection");  
  43.             //得到目標屬性的值(private屬性不能訪問,但可以通過調用setAccessible(true)實現訪問)  
  44.             String name = (String) fName.get(clazz);  
  45.             System.out.println(name);  
  46.               
  47.             fBoolean.setAccessible(true);  
  48.             /*得到目標屬性的布爾值,由於ReflectField類中的mBoolean屬性是非靜態的, 
  49.              * 所以此處的傳入實參爲目標屬性所在類的實例clazz.newInstance() 
  50.              */  
  51.             boolean mBoolean = fBoolean.getBoolean(clazz.newInstance());  
  52.             System.out.println(mBoolean);  
  53.               
  54.             fByte.setAccessible(true);  
  55.             //得到目標屬性的Byte類型值  
  56.             byte mByte = fByte.getByte(clazz.newInstance());  
  57.             System.out.println(mByte);  
  58.               
  59.             fShort.setAccessible(true);  
  60.             //得到目標屬性的short整型值  
  61.             short mShort = fShort.getShort(clazz);  
  62.             System.out.println(mShort);  
  63.               
  64.             fInt.setAccessible(true);  
  65.             //給目標屬性設置整型值      
  66.             fInt.setInt(clazz, 222);  
  67.             //得到目標屬性的整型值  
  68.             int mInt = fInt.getInt(clazz);  
  69.             System.out.println(mInt);  
  70.               
  71.             fLong.setAccessible(true);  
  72.             //給目標屬性設置Long整型值      
  73.             fLong.setLong(clazz, 2222);  
  74.             //得到目標屬性的Long整型值  
  75.             Long mLong = fLong.getLong(clazz);  
  76.             System.out.println(mLong);  
  77.               
  78.             fFloat.setAccessible(true);  
  79.             //給目標屬性設置float類型值  
  80.             fFloat.setFloat(clazz, 22222);  
  81.             //得到目標屬性的float類型值  
  82.             float mFloat = fFloat.getFloat(clazz);  
  83.             System.out.println(mFloat);  
  84.               
  85.             fDouble.setAccessible(true);  
  86.             //給目標屬性設置double類型值  
  87.             fDouble.setDouble(clazz, 222.222);  
  88.             //得到目標屬性的double類型值  
  89.             double mDouble = fDouble.getDouble(clazz);  
  90.             System.out.println(mDouble);  
  91.               
  92.             //給目標屬性設置字符值(private、protected屬性不能訪問)  
  93.             fChar.setChar(clazz, 'a');  
  94.             //得到目標屬性的字符值(private、protected屬性不能訪問)  
  95.             char mChar = fChar.getChar(clazz);  
  96.             System.out.println(mChar);  
  97.               
  98.             //目標屬性的名字,不侷限於修飾符,只要是類中聲明的屬性  
  99.             String name1 = fName.getName();  
  100.             System.out.println(name1);  
  101.             //目標屬性的類型,不侷限於修飾符  
  102.             Type type = fName.getGenericType();  
  103.             System.out.println(type);  
  104.             //目標屬性的類型對應的Class對象  
  105.             Class<?> clazz1 = fName.getType();      
  106.             System.out.println(clazz1);  
  107.             //目標屬性所在類對應的Class對象  
  108.             Class<?> clazz2 = fName.getDeclaringClass();   
  109.             System.out.println(clazz2);  
  110.             //目標屬性的權限修飾值(private爲2、protected爲4、public爲1)  
  111.             int modifier = fName.getModifiers();  
  112.             int modifier1 = fByte.getModifiers();  
  113.             int modifier2 = fShort.getModifiers();  
  114.             System.out.println(modifier);  
  115.             System.out.println(modifier1);  
  116.             System.out.println(modifier2);  
  117.               
  118.             System.out.println(fName.isAccessible());  
  119.             System.out.println(fChar.isAccessible());  
  120.               
  121.         } catch (NoSuchFieldException e) {  
  122.             // TODO Auto-generated catch block  
  123.             e.printStackTrace();  
  124.         } catch (SecurityException e) {  
  125.             // TODO Auto-generated catch block  
  126.             e.printStackTrace();  
  127.         } catch (IllegalArgumentException e) {  
  128.             // TODO Auto-generated catch block  
  129.             e.printStackTrace();  
  130.         } catch (IllegalAccessException e) {  
  131.             // TODO Auto-generated catch block  
  132.             e.printStackTrace();  
  133.         } catch (InstantiationException e) {  
  134.             // TODO Auto-generated catch block  
  135.             e.printStackTrace();  
  136.         }   
  137.     }  
  138.   
  139. }  

   3. Method:

       同Fiel一樣,一個Method對象對應描述一個類的方法;

       Class對象也提供了四種接口函數得到對應方法的Method對象,如下:       

       1). getMethod(String name, Class<?>... parameterTypes):返回類型爲Method,第一個參數name爲類中的方法名,第二個參數爲可變參數,傳入的是參數類型對應的Class對象(方法的參數可能爲多個的情況);該函數得到的是描述類中的一個public方法對應的Method對象;

      2). getMethods():返回類型爲Method類型數組,得到的是描述類中的所有public方法對應的Method對象;

      3). Method getDeclaredMethod(String name, Class<?>... parameterTypes)同getMethod(String name, Class<?>... parameterTypes),只不過得到的Method對象描述的不只是public方法, 還包括

protected、private方法,也是說只要是在類中聲明的方法;

      4). getDeclaredMethods():getMethods(),得到的是描述類中聲明的所有方法(public、protected、private)對應的FMethod對象;

   Method類的相關函數接口介紹:

   Method類提供的相關接口介紹:(注:在表中,Method對象對應的方法,姑且稱爲目標方法)

接口 返回類型 接口功能實現
setAccessible(boolean flag) void 參數爲true,只要是在類中聲明的目標方法均可訪問,爲false,只有public目標屬性可訪問
invoke(Object receiver, Object... args) Object 動態執行調用目標方法,第一個參數爲Class對象或者類的實例,第二個參數爲可變實參的對象(多個實參)
getDeclaringClass() Class<?> 得到目標方法所在類對應的Class對象
getExceptionTypes() Class<?> 得到目標方法拋出的異常類型對應的Class對象
getGenericExceptionTypes() Type[] 得到目標方法拋出的異常類型對應的Type對象
getReturnType() Class<?> 得到目標方法返回類型對應的Class對象
getGenericReturnType() Type 得到目標方法返回類型對應的Type對象
getParameterTypes() Class<?>[] 得到目標方法各參數類型對應的Class對象
getGenericParameterTypes() Type[] 得到目標方法各參數類型對應的Type對象
getModifiers() int 得到目標方法修飾符的值
getName() String 得到目標方法的名字

   下面就以一個示例代碼來驗證Method表中的函數接口的實現,如下:

   1). MethodBeReflected.java(被反射的類)

[java] view plaincopy
  1. package com.stevenhu.method;  
  2.   
  3. public class MethodBeReflected  
  4. {  
  5.   
  6.     private static String mName;  
  7.     private static int mAge;  
  8.     private static float mWeight;  
  9.       
  10.     private String getmName()  
  11.     {  
  12.         return mName;  
  13.     }  
  14.   
  15.     protected void setmName(String mName)  
  16.     {  
  17.         this.mName = mName;  
  18.     }  
  19.   
  20.     protected static int getmAge()  
  21.     {  
  22.         return mAge;  
  23.     }  
  24.   
  25.     private static void setmAge(int age)   
  26.     {  
  27.         mAge = age;  
  28.     }  
  29.   
  30.     private float getmWeight() throws Exception, NoSuchMethodException, SecurityException  
  31.     {  
  32.         return mWeight;  
  33.     }  
  34.   
  35.     protected void setmWeight(float mWeight)   
  36.     {  
  37.         this.mWeight = mWeight;  
  38.     }  
  39.   
  40.     private void setAllValues(String name, int age, float weight)  
  41.     {  
  42.         this.mName = name;  
  43.         this.mAge = age;  
  44.         this.mWeight = weight;  
  45.     }  
  46. }  

    2)ReflectMethod.java(執行反射的類)

[java] view plaincopy
  1. package com.stevenhu.reflection.test;  
  2.   
  3. import java.lang.reflect.InvocationTargetException;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Type;  
  6.   
  7. import com.stevenhu.method.MethodBeReflected;  
  8.   
  9. public class ReflectMethod   
  10. {  
  11.       
  12.     /** 
  13.      * @param args 
  14.      */  
  15.     public static void main(String[] args)   
  16.     {  
  17.         // TODO Auto-generated method stub  
  18.   
  19.         Class<?> clazz = MethodBeReflected.class;  
  20.           
  21.         try   
  22.         {  
  23.             //第一個實參爲方法名,第二個實參爲方法參數類型對應的class對象  
  24.             Method nameMethod = clazz.getDeclaredMethod("setmName", String.class);  
  25.             Method ageMethod = clazz.getDeclaredMethod("setmAge"int.class);  
  26.             Method weightMethod = clazz.getDeclaredMethod("setmWeight"float.class);  
  27.             Method allValuesMethod = clazz.getDeclaredMethod("setAllValues"new Class[]{String.classint.classfloat.class});  
  28.               
  29.             nameMethod.setAccessible(true);  
  30.             //調用setmName方法,給ReflectMethod類中的屬性mName賦值爲"stevenhu"  
  31.             nameMethod.invoke(clazz.newInstance(), "lisa");       
  32.             nameMethod = clazz.getDeclaredMethod("getmName"null);  
  33.             nameMethod.setAccessible(true);  
  34.             //調用getmName方法,得到mName的值  
  35.             String name1 = (String) nameMethod.invoke(clazz.newInstance(), null);  
  36.             System.out.println(name1);  
  37.               
  38.             ageMethod.setAccessible(true);  
  39.             /*調用setmAge方法設置年齡,由於該方法是靜態方法,所以第一個實參可爲類的Class對象clazz, 
  40.              * 也可以是類的對象clazz.newInstance(); 
  41.              */  
  42.             ageMethod.invoke(clazz, 21);  
  43.             ageMethod = clazz.getDeclaredMethod("getmAge"null);  
  44.             ageMethod.setAccessible(true);  
  45.             //調用getmAge方法,得到之前設置的年齡  
  46.             int age1 = (Integer) ageMethod.invoke(clazz, null);   
  47.             System.out.println(age1);  
  48.               
  49.             weightMethod.setAccessible(true);  
  50.             //調用setmWeight方法,設置體重  
  51.             weightMethod.invoke(clazz.newInstance(), new Float(50.5));  
  52.             weightMethod = clazz.getDeclaredMethod("getmWeight",null);  
  53.             weightMethod.setAccessible(true);  
  54.             //調用getmWeight方法,得到之前設置的體齡  
  55.             float weight1 = (Float) weightMethod.invoke(clazz.newInstance(), null);   
  56.             System.out.println(weight1);  
  57.               
  58.             allValuesMethod.setAccessible(true);  
  59.             /*調用ReflectMethod的setAllValues方法賦值 
  60.              * 注:此處不能直接傳入實參63.5;浮點型必須創建Float對象 
  61.              * 整型和字符串可創建Integer、String對象,也可以不創建 
  62.              */  
  63.             //allValuesMethod.invoke(clazz.newInstance(), new String("stevenhu"), new Integer(23), new Float(63.5));  
  64.             allValuesMethod.invoke(clazz.newInstance(), "stevenhu"23new Float(63.5));  
  65.               
  66.             nameMethod = clazz.getDeclaredMethod("getmName"null);  
  67.             nameMethod.setAccessible(true);  
  68.             String name2 = (String) nameMethod.invoke(clazz.newInstance(), null);  
  69.             System.out.println(name2);  
  70.               
  71.             ageMethod = clazz.getDeclaredMethod("getmAge"null);  
  72.             ageMethod.setAccessible(true);  
  73.             int age2 = (Integer) ageMethod.invoke(clazz.newInstance(), null);         
  74.             System.out.println(age2);  
  75.               
  76.             weightMethod = clazz.getDeclaredMethod("getmWeight"null);  
  77.             weightMethod.setAccessible(true);  
  78.             float weight2 = (Float) weightMethod.invoke(clazz.newInstance(), null);       
  79.             System.out.println(weight2);  
  80.               
  81.             //得到目標方法所在類對應的Class對象  
  82.             Class<?> clazz1 = weightMethod.getDeclaringClass();  
  83.               
  84.             //得到目標方法拋出的異常類型對應的Class對象  
  85.             Class<?>[] clazzs1 = weightMethod.getExceptionTypes();  
  86.             for (Class cl : clazzs1)  
  87.             {  
  88.                 System.out.println(cl);  
  89.             }             
  90.             //得到目標方法拋出的異常類型對應的Type對象  
  91.             Type[] types1 = weightMethod.getGenericExceptionTypes();  
  92.             //得到目標方法返回類型對應的Class對象  
  93.             Class<?> clazz2 = nameMethod.getReturnType();  
  94.             //得到目標方法返回類型對應的Type對象  
  95.             Type type = nameMethod.getGenericReturnType();  
  96.             //得到目標方法各參數類型對應的Class對象  
  97.             Class<?>[] clazzs2 = allValuesMethod.getParameterTypes();  
  98.             //得到目標方法各參數類型對應的Type對象  
  99.             Type[] types2 = allValuesMethod.getGenericParameterTypes();  
  100.             //得到目標方法修飾符的值  
  101.             int modifier = ageMethod.getModifiers();  
  102.             System.out.println(modifier);  
  103.             //得到目標方法的名字  
  104.             String methodName = nameMethod.getName();  
  105.             System.out.println(nameMethod.isVarArgs());  
  106.               
  107.         } catch (NoSuchMethodException e)   
  108.         {  
  109.             // TODO Auto-generated catch block  
  110.             e.printStackTrace();  
  111.         } catch (SecurityException e)   
  112.         {  
  113.             // TODO Auto-generated catch block  
  114.             e.printStackTrace();  
  115.         } catch (IllegalAccessException e) {  
  116.             // TODO Auto-generated catch block  
  117.             e.printStackTrace();  
  118.         } catch (IllegalArgumentException e) {  
  119.             // TODO Auto-generated catch block  
  120.             e.printStackTrace();  
  121.         } catch (InvocationTargetException e) {  
  122.             // TODO Auto-generated catch block  
  123.             e.printStackTrace();  
  124.         } catch (InstantiationException e) {  
  125.             // TODO Auto-generated catch block  
  126.             e.printStackTrace();  
  127.         }  
  128.     }  
  129.   
  130. }  
本人用於學習記錄,非常感謝2位

轉載:http://blog.csdn.net/stevenhu_223/article/details/9286121

轉載:http://blog.csdn.net/ritterliu/article/details/7764849


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章