Java反射框架(三)(完結)——Constructor、Array、Enum
目錄
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方法。