1. 程式人生 > >Java反射框架(三)(完結)——Constructor、Array、Enum

Java反射框架(三)(完結)——Constructor、Array、Enum

目錄

4.1陣列

4.2列舉

3.Members

3.3Constructors

構造器用來建立類的物件。

獲取Constructor

獲取特定構造器

Constructor con = c.getConstructor(int.class, int.class);
Constructor con = c.getDeclaredConstructor(int.class, int.class);

獲取所有構造器

Constructor[] cons = c.getConstructors();
Constructor[] cons = c.getDeclaredConstructors();

獲取構造器引數型別

Class[] cpcs = con.getParameterTypes();
Type[] tcs = con.getGenericParameterTypes();

note:前者會受到泛型型別擦除的影響,泛型表示為java.lang.Object,後者不會受影響,返回泛型。

判斷構造器是否包含變參

boolean b = con.isVarArgs();

判斷構造器是否為合成

boolean b = con.isSynthetic();

檢索解析修飾符

獲取構造器修飾符

int mods = con.getModifiers();

ps:無法獲取到package-private修飾符,需要手動判斷。

Constructor實現了AnnotatedElement介面,提供了檢索構造器所持有的註解的API。

建立例項

Constructor.newInstance()與Class.newInstance()都可以用用來建立例項。

  • Class.newInstance()只能呼叫無參構造器,Constructor.newInstance()沒有引數數量限制。
  • Class.newInstance()會將構造器丟擲的異常直接丟擲。
  • Constructor.newInstance()丟擲包裝後的InvocationTargetException。
  • Class.newInstance()要求構造器可見,Constructor.newInstance()可呼叫private構造器。

Class.newInstance()

Object obj = c.newInstance();

Constructor.newInstance()

Object o = con.newInstance(1);

4.陣列與列舉型別

在JVM的視角,列舉與陣列是類。所以Class的方法也可以用於列舉與陣列。

4.1陣列

反射框架提供了方法用來訪問陣列型別、陣列元件型別、建立新陣列檢索設定陣列元件值。

java.lang.reflect.Array提供了運算元組的方法。

識別陣列型別

判斷型別是否為陣列

boolean b = c.isArray();

note:判斷Class物件c表示的型別是否為陣列,是陣列返回true。

獲取元件型別

Class c = ac.getComponentType();

note:獲取Class物件ac表示的陣列型別的元件型別。

建立新陣列

建立新陣列

Object obj = Array.newInstance(c, 5);

note:建立長度為5,元件型別為Class物件c表示的型別的陣列。

建立陣列

String[][][] arr = (String[][][]) Array.newInstance(String.class, 3, 4, 5);

note:建立長度為3的三維陣列arr。

note:三維陣列的元件為長度為4的二維陣列,二維陣列的元件為長度為5的字串陣列。

訪問設定陣列及其元件

獲取陣列元件值

Object ans = Array.get(obj, 2);

note:獲取陣列obj的下標為2的元件的值。

ps:get用於獲取引用型別陣列的元素。

ps:getInt、getDouble、getFloat、getShort、getLong、getByte、getChar、getBoolean用於獲取原始型別陣列的元素。

設定陣列元件值

Array.set(obj, i, val);

note:將陣列obj的第i個位置設定為val。

ps:set用於設定元素型別為引用型別的陣列的元素。

ps:setInt、setDouble、setFloat、setShort、setLong、setByte、setChar、setBoolean用於設定元素型別為原始型別的陣列的元素。

ps:使用setInt方法為Integer型別的陣列設值時,由於反射機制發生在執行時,傳入的原始型別無法裝箱,將導致異常。可以使用set方法傳參,解決這一問題。

4.2列舉

列舉型別是類,所以使用Class內的方法即可操作列舉型別。

列舉是單例,所以不能例項化,使用反射強行例項化列舉型別會丟擲異常。

檢驗列舉

判斷型別是否為列舉

boolean b = c.isEnum();

note:如果Class型別物件c表示的型別為列舉,返回true。

獲取列舉常量列表

R[] rs = (R[]) c.getEnumConstants();

note:如果Class型別物件c表示的型別為列舉,獲取此列舉型別定義的所有常量,如果不是列舉返回null。

ps:此方法與列舉物件的預設方法values()效果相同。

ps:此方法按照列舉常量宣告的順序返回列舉常量。

判斷域是否為列舉常量

boolean b = f.isEnumConstant();

note:判斷Field型別物件f表示的域是否為列舉常量,是則返回true。

ps:列舉常量,即定義在列舉類中的常量域。

訪問設定列舉型別域

訪問設定列舉型別域與訪問普通的域沒有區別,都是使用Field.get與Field.set方法。