java利器——反射機制

一個快樂的小猿類發表於2018-12-17

java反射的概念:java的反射機制是指在執行狀態下,對於一個類來說,可以得到這個類的所有方法和屬性。對於一個物件來說,可以呼叫這個物件的人和方法和屬性。 反射機制首先會拿到該類的位元組碼檔案(Class檔案),然後反向獲取這個類的所有資訊。(注意:一個型別的類在執行中,只產生一個class檔案

既然反射的前置條件是獲取class類,所以不得不提出獲取class的方法。

獲取class的幾種方式:

(1)Persion p=new Persion();

       Class c=p.getClass();

     該方法不推薦使用,因為已經有了persion物件,反射多此一舉。

(2)Class c=Persion.class;

      任意的類都是繼承object類,任何類也都有.class屬性,說明object裡面有一個class用來獲取類的資訊,但是該方法需要倒入包,依賴強。

(3)Class c =Class.forName(“com.xxxx.xxxx”)

      推薦第三種,無序導包,效率較高。

   以上三種方法獲得的c物件都是同一個物件,因為類在執行的過程中,只產生一個class檔案。

反射重要的類和方法

(1)Class類

      getName():獲得類的完整名字。
  getFields():獲得類的public型別的屬性。
  getDeclaredFields():獲得類的所有屬性。包括private 宣告的和繼承類
  getMethods():獲得類的public型別的方法。
  getDeclaredMethods():獲得類的所有方法。包括private 宣告的和繼承類
  getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name引數指定方法的名字,parameterTypes 引數指定方法的引數型別。
  getConstructors():獲得類的public型別的構造方法。
  getConstructor(Class[] parameterTypes):獲得類的特定構造方法,parameterTypes 引數指定構造方法的引數型別。
  newInstance():通過類的不帶引數的構造方法建立這個類的一個物件。

boolean isPrimitive = class1.isPrimitive();//判斷是否是基礎型別
boolean isArray = class1.isArray();//判斷是否是集合類
boolean isAnnotation = class1.isAnnotation();//判斷是否是註解類
boolean isInterface = class1.isInterface();//判斷是否是介面類
boolean isEnum = class1.isEnum();//判斷是否是列舉類
boolean isAnonymousClass = class1.isAnonymousClass();//判斷是否是匿名內部類
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);//判斷是否被某個註解類修飾

String className = class1.getName();//獲取class名字 包含包名路徑
Package aPackage = class1.getPackage();//獲取class的包資訊
String simpleName = class1.getSimpleName();//獲取class類名
int modifiers = class1.getModifiers();//獲取class訪問許可權

Class<?>[] declaredClasses = class1.getDeclaredClasses();//內部類
Class<?> declaringClass = class1.getDeclaringClass();//外部類

 

(2)Field類(一般於Class類連用)

      Class c =Class.forName(“XXXX”);

      Field  fields=c.getDeclaredFields(“fieldName”);

      fields.setAccessible(true);//設定私有變數可訪問

      Object obj=c.newInstance();

      fields.set(obj,”xxx”)//設定變數的值

(3)Method

Class.forName(“com.XXX.XXX.” + className).newInstance().getMethod(“methodName”).invoke(“methodName”,String …)//呼叫反射物件的方法

(4)Constructor類

 Constructor<?> cons=Class.forName(“com.XXX.XXX.” + className).getConstructor(Param.class)//Param可謂int,String,Object等,對應著物件的param型別的構造方法。

cons.newInstance(Param.class.newInstance());//param的具體值(物件)

 

 

 

 

 

反射的應用場景:

(1)簡單工廠

(2)代理模式

(3)一般還和配置檔案共同使用

Class clazz = Class.forName(“com.XXX.XXX.” + className);//className為配置檔案className的值
Object obj = clazz.newInstance();
Method method = clazz.getMethod(methodName);//methodName為配置檔案methodName的值
method.invoke(obj);

 

歡迎大家批評指正,共同學習,共同進步。

 

相關文章