三種方式獲取Class對象java
public class SubPerson extends Person { public Long subId; private String subName; private SubPerson() { } public SubPerson(Long subId, String subName) { this.subId = subId; this.subName = subName; } } public class Person { public Long id; private String name; public Person() { } class Card{ private String id; public Card() { } public String getId() { return id; } public void setId(String id) { this.id = id; } } } //1 Class personClass1 = new Person().getClass(); System.out.println(personClass1); //2 Class personClass2 = Person.class; System.out.println(personClass2); //3 try { Class personClass3 = Class.forName("com.banary.reflect.Person"); System.out.println(personClass3); }catch (ClassNotFoundException e){ e.printStackTrace(); }
public static void ClassMethodTest(){ //獲取全類名 System.out.println(Person.class.getName()); System.out.println(int.class.getName()); System.out.println(int[][][].class.getName()); System.out.println(Person.Card.class.getName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getName()); Runnable runnable = ()-> System.out.println("test"); System.out.println(runnable.getClass().getName()); System.out.println("------------分割線------------"); //獲取類名 System.out.println(Person.class.getSimpleName()); System.out.println(int.class.getSimpleName()); System.out.println(int[][][].class.getSimpleName()); System.out.println(Person.Card.class.getSimpleName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getSimpleName()); System.out.println(runnable.getClass().getSimpleName()); System.out.println("------------分割線------------"); /** * 獲取官方類名 * 1. getCanonicalName() 返回的也是全限定類名,可是對於內部類,不用 $ 開頭,而用 .。 * 2. getCanonicalName() 對於數組類型的 Class,同 simplename 同樣直接在後面添加 [] 。 * 3. getCanonicalName() 不一樣於 simplename 的地方是,不存在 canonicalName 的時候返回 null 而不是空字符串。 * 4. 局部類和匿名內部類不存在 canonicalName。 */ System.out.println(Person.class.getCanonicalName()); System.out.println(int.class.getCanonicalName()); System.out.println(int[][][].class.getCanonicalName()); System.out.println(Person.Card.class.getCanonicalName()); System.out.println(new Runnable() { @Override public void run() { } }.getClass().getCanonicalName()); System.out.println(runnable.getClass().getCanonicalName()); }
// 十進制 System.out.println(Modifier.class.getModifiers()); // 十六進制 System.out.println(Integer.toHexString(Modifier.class.getModifiers())); // 對應的真實修飾符 System.out.println(java.lang.reflect.Modifier.toString(Modifier.class.getModifiers()));
經過上述的方法,可見java中是採用二進制位來表示修飾符,下列爲java中修飾符實現數組
public class Modifier { // 2^0 public static final int PUBLIC = 0x00000001; // 2^1 public static final int PRIVATE = 0x00000002; // 2^2 public static final int PROTECTED = 0x00000004; public static final int STATIC = 0x00000008; public static final int FINAL = 0x00000010; public static final int SYNCHRONIZED = 0x00000020; public static final int VOLATILE = 0x00000040; public static final int TRANSIENT = 0x00000080; public static final int NATIVE = 0x00000100; public static final int INTERFACE = 0x00000200; public static final int ABSTRACT = 0x00000400; public static final int STRICT = 0x00000800; public static String toString(int mod) { StringBuilder sb = new StringBuilder(); int len; if ((mod & PUBLIC) != 0) sb.append("public "); if ((mod & PROTECTED) != 0) sb.append("protected "); if ((mod & PRIVATE) != 0) sb.append("private "); /* Canonical order */ if ((mod & ABSTRACT) != 0) sb.append("abstract "); if ((mod & STATIC) != 0) sb.append("static "); if ((mod & FINAL) != 0) sb.append("final "); if ((mod & TRANSIENT) != 0) sb.append("transient "); if ((mod & VOLATILE) != 0) sb.append("volatile "); if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized "); if ((mod & NATIVE) != 0) sb.append("native "); if ((mod & STRICT) != 0) sb.append("strictfp "); if ((mod & INTERFACE) != 0) sb.append("interface "); if ((len = sb.length()) > 0) /* trim trailing space */ return sb.toString().substring(0, len-1); return ""; } }
類的屬性包括Field、Method、Constructorapp
Class personClass = SubPerson.class; //獲取自身的全部的 public 屬性,包括從父類繼承下來的, 可能會拋出運行時異常SecurityException Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); } //根據field名獲取, 可能會拋出NoSuchFieldException(檢查型), SecurityException try { Field field1 = personClass.getField("subId"); System.out.println(field1.getName()); } catch (NoSuchFieldException e){ e.printStackTrace(); } System.out.println("------------分割線------------"); //獲取全部的屬性,但不包括從父類繼承下來的屬性 Field[] declaredFields = personClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField.getName()); } System.out.println("------------分割線------------"); try{ Field field2 = personClass.getDeclaredField("subName"); System.out.println(field2.getName()); } catch (NoSuchFieldException e){ e.printStackTrace(); }
# 可以獲取到泛型類型 public Type getGenericType() {} public Class<?> getType() {}
# 同class和Method的修飾符同樣 public int getModifiers() {}
#設置值 public Object get(Object obj); public int getInt(Object obj); public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException; public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException; public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException; public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException; public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException; public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException; public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException public void set(Object obj, Object value); # 獲取值 public void getInt(Object obj,int value); public void getLong(Object obj,long value) throws IllegalArgumentException, IllegalAccessException; public void getFloat(Object obj,float value) throws IllegalArgumentException, IllegalAccessException; public void getShort(Object obj,short value) throws IllegalArgumentException, IllegalAccessException; public void getDouble(Object obj,double value) throws IllegalArgumentException, IllegalAccessException; public void getChar(Object obj,char value) throws IllegalArgumentException, IllegalAccessException; public void getByte(Object obj,byte b) throws IllegalArgumentException, IllegalAccessException; public void getBoolean(Object obj,boolean b) throws IllegalArgumentException, IllegalAccessException
Class 自己不對成員進行儲存,它只提供檢索,因此須要用 Field、Method、Constructor 對象來承載這些成員,因此,針對成員的操做時,通常須要爲成員指定類的實例引用。ide
getName()
#獲取全部的參數 public Parameter[] getParameters() {} // 獲取全部的參數類型 public Class<?>[] getParameterTypes() {} // 獲取全部的參數類型,包括泛型 public Type[] getGenericParameterTypes() {}
// 獲取返回值類型 public Class<?> getReturnType() {} // 獲取返回值類型包括泛型 public Type getGenericReturnType() {}
public int getModifiers() {}
public Class<?>[] getExceptionTypes() {} # 包括泛型 public Type[] getGenericExceptionTypes() {}
#invoke() 方法中第一個參數 Object 實質上是 Method 所依附的 Class 對應的類的實例,若是這個方法是一個靜態方法,那麼 ojb 爲 null,後面的可變參數 Object 對應的天然就是參數 #invoke() 返回的對象是 Object,因此實際上執行的時候要進行強制轉換。 #在對 Method 調用 invoke() 的時候,若是方法自己會拋出異常,那麼這個異常就會通過包裝,由 Method 統一拋出 InvocationTargetException。而經過 InvocationTargetException.getCause() 能夠獲取真正的異常。 public Object invoke(Object obj, Object... args) {}
public static void getConstructor(){ Class subPersonClass = SubPerson.class; //獲取全部的public構造器,因爲父類的構造器不能繼承,因此獲取不到 Constructor[] constructors = subPersonClass.getConstructors(); for (Constructor c : constructors) { System.out.println(c.toString()); } System.out.println("------------分割線------------"); //獲取全部的構造器,包括私有和公開的 Constructor[] declaredConstructors = subPersonClass.getDeclaredConstructors(); for (Constructor declaredConstructor :declaredConstructors) { System.out.println(declaredConstructor.toString()); } }
# Class.newInstance() 只能調用無參的構造方法,而 Constructor.newInstance() 則能夠調用任意的構造方法。 # Class.newInstance() 經過構造方法直接拋出異常,而 Constructor.newInstance() 會把拋出來的異常包裝到 InvocationTargetException 裏面去,這個和 Method 行爲一致。 # Class.newInstance() 要求構造方法可以被訪問,而 Constructor.newInstance() 卻可以訪問 private 修飾的構造器。
getName(); #獲取數組的裏面的元素的類型,好比 int[] 數組的 componentType 天然就是 int getComponentType();
public static Object newInstance(Class<?> componentType, int... dimensions) throws IllegalArgumentException, NegativeArraySizeException {}
e.g.ui
# 建立一個 int[2][3] 的數組 Array.newInstance(int.class,2,3);
public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException; public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException; public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static void setBoolean(Object array, int index, boolean z) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException; public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
// 用來斷定 Class 對象是否是枚舉類型 Class.isEnum() // 獲取全部的枚舉常量 Class.getEnumConstants() // 判斷一個 Field 是否是枚舉常量 Field.isEnumConstant()
public static void reflectEnum() throws Exception{ Class colorClass = Color.class; if(colorClass.isEnum()){ System.out.println(String.format("class Color %s is Enum", colorClass.getName())); Field[] fields = colorClass.getDeclaredFields(); for (Field field:fields) { if(field.isEnumConstant()){ System.out.println(String.format("%s is EnumConstant", field.getName())); }else{ System.out.println(String.format("%s is not EnumConstant", field.getName())); } } } System.out.println("_____________________"); Constructor[] constructors = colorClass.getDeclaredConstructors(); for(Constructor constructor : constructors){ System.out.println(constructor.getName()); constructor.setAccessible(true); Color color = (Color) constructor.newInstance("123123"); System.out.println(color.getKey()); } Color color = (Color) colorClass.newInstance(); System.out.println(color.getKey()); }