Java註解和反射04:獲取類的執行時結構
阿新 • • 發佈:2022-03-16
獲取執行時類的完整結構
通過反射可以獲得類實現的介面、父類、構造器、方法、屬性、註解
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Main { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class<?> c1 = Class.forName("Test"); /** * getName()方法獲得類名 */ System.out.println(c1.getName()); System.out.println(); /** * getDeclaredFields()方法獲得所有屬性,包括私有屬性 * getFields()方法只能獲得所有public屬性 */ Field[] fields = c1.getDeclaredFields(); for (Field field : fields){ System.out.println(field); } System.out.println(); /** * getDeclaredField()方法獲得指定屬性,包括私有屬性 */ Field field = c1.getDeclaredField("name"); System.out.println(field); System.out.println(); /** * getDeclaredMethods()方法獲得本類的所有方法,包括私有方法 * getMethods()方法獲得本類和父類的所有public方法 */ Method[] methods = c1.getDeclaredMethods(); for (Method method : methods){ System.out.println(method); } System.out.println(); /** * getDeclaredMethod()方法獲得指定方法,包括私有方法 * 如果由引數,需要傳入引數型別對應的Class物件 */ Method method = c1.getDeclaredMethod("test", String.class); System.out.println(method); System.out.println(); /** * getDeclaredConstructors()方法獲得所有構造器,包括私有構造器 * getConstructors()方法只能獲得public構造器 */ Constructor[] constructors = c1.getDeclaredConstructors(); for (Constructor constructor : constructors){ System.out.println(constructor); } System.out.println(); /** * getDeclaredConstructor()方法獲得指定構造器,包括私有構造器 * 需要傳入引數型別對應的Class物件 */ Constructor<?> constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); System.out.println(constructor); } } class Test { private String name; int age; int money; public Test(){} private Test(String name, int age, int money){ this.name = name; this.age = age; this.money = money; } private void test(String name) { System.out.println(name + "的test()方法"); } private void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Test{" + "name='" + name + '\'' + ", age=" + age + ", money=" + money + '}'; } }
建立執行時類的物件、呼叫執行時類的指定結構
- 呼叫Class物件的newInstance()方法,建立執行時類的物件
- 如果有無參構造器且許可權足夠,可以直接建立物件,屬性為預設值
- 如果沒有無參構造器,需要用getDeclaredConstructor()方法獲得指定的有參構造器,傳入引數型別對應的Class物件,再通過Constructor例項化物件
- Method、Field、Constructor物件都有setAccessible()方法
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Main { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<?> c1 = Class.forName("Test"); /** * 建立物件 * 預設呼叫無參構造器的newInstance()方法建立物件,需要強制轉換一下型別 */ Test test = (Test) c1.newInstance(); System.out.println(test); /** * 沒有無參構造器,可以呼叫指定的有參構造器建立物件 * 先獲得一個有參構造器物件,再建立物件 * 如果是私有構造器,需要用setAccessible(true)方法關閉程式的安全檢測 */ Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class); constructor.setAccessible(true); Test test2 = (Test) constructor.newInstance("ty", 24, 10000); System.out.println(test2); /** * 呼叫方法 * 先獲得一個指定方法的物件,再通過invoke()方法啟用要呼叫的方法 * 如果是私有方法,需要用setAccessible(true)方法關閉程式的安全檢測 */ Method method = c1.getDeclaredMethod("setName", String.class); method.setAccessible(true); method.invoke(test2, "ttyy"); System.out.println(test2.getName()); /** * 操作屬性 * 先獲得一個指定屬性的物件,再通過set()方法修改屬性 * 如果是私有屬性,需要用setAccessible(true)方法關閉程式的安全檢測 */ Field field = c1.getDeclaredField("name"); field.setAccessible(true); field.set(test2, "tttyyy"); System.out.println(test2.getName()); } } class Test { private String name; int age; int money; public Test(){} private Test(String name, int age, int money){ this.name = name; this.age = age; this.money = money; } private void test(String name) { System.out.println(name + "的test()方法"); } private void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "Test{" + "name='" + name + '\'' + ", age=" + age + ", money=" + money + '}'; } }