public class DemoClass {
private String nickName;
public int num = 3;
public int add(int a,int b){
return a + b;
}
public int sub(int a,int b){
return a - b;
}
static {
System.out.println("DemoClass靜態代碼塊");
}
{
System.out.println("DemoClass動態代碼塊");
}
public DemoClass(){}
public DemoClass(String string){
System.out.println("DemoClass構造方法");
}
public String getNickName() {
return nickName;
}
public void setNickName(String name) {
this.nickName = name;
}
public int getNum() {
return num;
}
private void testMethod(){
System.out.println("靜態方法");
}
-
獲取類對象
- 直接調用某一個類的class屬性(不知道這樣說合適不合適)
- 調用某一個對象的getClass方法
- 調用Class類的靜態方法forName
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { Class<?> classDemo = DemoClass.class;//class demo.DemoClass//不會調用任何方法 Class<?> classNew = new DemoClass().getClass();//class demo.DemoClass 靜態代碼塊和動態代碼塊還有構造方法都會執行 Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只會調用靜態代碼塊 System.out.println(forName);//class demo.DemoClass System.out.println(classDemo == classNew);//true System.out.println(classNew == forName);//true System.out.println(forName == classDemo);//true } }
-
獲取類實例
- 通過newInstance,這種是調用單獨無參構造函數,所以如果沒有無參構造函數就會異常
- 獲取指定的構造函數,再通過指定的構造函數的newInstance創建實例
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass"); try { Object o = forName.newInstance();//這種每次獲取的都是同一個對象,class必須有無參構造函數,否則會報錯 System.out.println(o);//demo.ReflectDemo@14ae5a } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } try { Constructor<?> constructor = forName.getConstructor(String.class); Object parade = constructor.newInstance("parade"); Object year = constructor.newInstance("year"); System.out.println(parade);//demo.DemoClass@7f31245a System.out.println(year);//demo.DemoClass@6d6f6e28 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { e.printStackTrace(); } }
-
獲取屬性
-
getFields->不能獲取私有屬性
-
getDeclaredFields->可以獲取私有屬性
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只會調用靜態代碼塊 try { Field name = forName.getField("name");//name是私有,則會拋異常 } catch (NoSuchFieldException e) { e.printStackTrace(); } Field[] fields = forName.getFields();//獲取所有非私有屬性 for (Field field : fields) { System.out.println(field.getName()); } try { Field name = forName.getDeclaredField("name"); System.out.println(name); } catch (NoSuchFieldException e) { e.printStackTrace(); } Field[] declaredFields = forName.getDeclaredFields();//獲取所有屬性 for (Field declaredField : declaredFields) { System.out.println(declaredField.getName()); } }
-
屬性賦值
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只會調用靜態代碼塊 try { Field name = forName.getDeclaredField("nickName"); DemoClass o = (DemoClass) forName.newInstance();//通過Class對象得到實例對象 name.setAccessible(true);//將私有屬性設置爲可訪問 name.set(o,"parade");//給私有屬性賦值 System.out.println(o.getNickName());//驗證賦值成功 Field num = forName.getField("num");//非私有屬性賦值 num.setInt(o,5); System.out.println(o.getNum());//驗證賦值成功 Object o1 = num.get(o);//或者繼續通過反射獲取屬性值 System.out.println(o1); } catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) { e.printStackTrace(); } }
-
-
獲取方法->類似獲取屬性
-
getMethod->不能獲取私有方法
-
getDeclaredMethods
Method[] methods = forName.getMethods();//會得到所有非private方法,包括父類的方法 for (Method method : methods) { System.out.println(method.getName()); } Method[] declaredMethods = forName.getDeclaredMethods();//獲取本類的所有方法,不包括父類 for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod.getName()); }
-
調用方法
public static void main(String[] args) throws ClassNotFoundException { Class<?> forName = Class.forName("demo.DemoClass");//class demo.ReflectDemo,只會調用靜態代碼塊 try { DemoClass demoClass = (DemoClass) forName.newInstance();//調用方法前先要獲得一個實例對象才能調用實例對象的方法 Method setNickName = forName.getMethod("setNickName", String.class); Method getNickName = forName.getMethod("getNickName"); setNickName.invoke(demoClass, "Are you ok"); System.out.println(getNickName.invoke(demoClass)); Method testMethod = forName.getDeclaredMethod("testMethod"); testMethod.setAccessible(true);//調用私有方法同樣要設置可訪問 testMethod.invoke(demoClass); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } }
-