※屬性設值取值
package inheritate;
public class Son {
public String s1;
private String s2;
}
------------------------------
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("inheritate.Son");
Field s1 = clazz.getField("s1");
Object s1Obj = clazz.newInstance();
s1.set(s1Obj, "xxx");
System.out.println(s1.get(s1Obj));
// Field s2 = clazz.getField("s2");
Field s2 = clazz.getDeclaredField("s2");
s2.setAccessible(true);
Object s2Obj = clazz.newInstance();
s2.set(s2Obj, "ooo");
System.out.println(s2.get(s2Obj));
}
※修飾子不是public的,有可能會報「NoSuchFieldException」的錯,得看測試類在放在哪而定
※想取得上面報的錯的值,可用setAccessible,但得用DeclaredField才行,不然還是會報錯,因為DeclaredField本來就是取自己class的東西
※AccessibleObject.setAccessible
Field和Method到最後都會繼承AccessibleObject類別,所以setAccessible都可以用setAccessible是個overloadding,有分一個參數和兩個參數,兩個參數是static的
一個參數上個例子已有,這裡講的是兩個參數的
package inheritate;
public class Son {
private String s0;
private String s1;
private String s2;
private String s3;
private String s4;
}
------------------------------
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("inheritate.Son");
Field[] fields = clazz.getDeclaredFields();
Object obj = clazz.newInstance();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
fields[i].set(obj, "s" + i);
System.out.println("field name=" + fields[i].getName());
System.out.println("field value=" + fields[i].get(obj));
System.out.println();
}
}
※這個例子還是和上個例子一樣,跑迴圈時,一個一個變成true
※
Class<?> clazz = Class.forName("inheritate.Son");
Field[] fields = clazz.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
Object obj = clazz.newInstance();
for (int i = 0; i < fields.length; i++) {
// f.setAccessible(fields, true);
fields[i].set(obj, "s" + i);
System.out.println("field name=" + fields[i].getName());
System.out.println("field value=" + fields[i].get(obj));
System.out.println();
}
※使用靜態方法可以一次將屬性全部變成true
※註解那行也是可以,但浪費一些資源,而且會有警告,因為它是static
※方法設值取值
package inheritate;
public class Son {
public String sayHello() {
return "hello";
}
public String say(String data) {
return data;
}
private String privateTest() {
return "private method";
}
}
------------------------------
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("inheritate.Son");
// 呼叫無參方法
Method m1 = clazz.getMethod("sayHello");
String r1 = (String) m1.invoke(clazz.newInstance());
System.out.println(r1);
// 呼叫有參方法
Method m2 = clazz.getMethod("say", String.class);
String r2 = (String) m2.invoke(clazz.newInstance(), "Hello Reflection");
System.out.println(r2);
// 取得private方法
// Method m3 = clazz.getMethod("privateTest");
Method m3 = clazz.getDeclaredMethod("privateTest");
m3.setAccessible(true);
String r3 = (String) m3.invoke(clazz.newInstance());
System.out.println(r3);
}
※修飾子不是public的,有可能會報「NoSuchMethodException」的錯,得看測試類在放在哪而定
※想取得上面報的錯的值,可用setAccessible,但得用DeclaredMethod才行,不然還是會報錯,因為DeclaredField本來就是取自己class的東西
※invoke就是呼叫方法了,裡面至少要放實體,如果沒有回傳值也不會報錯,會回傳null
※setter/getter
package inheritate;
public class Son {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
------------------------------
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("inheritate.Son");
Object obj = clazz.newInstance();
Class<?> cz = obj.getClass();
Method m1 = cz.getMethod("setId", int.class);
m1.invoke(obj, 1);
Method m2 = cz.getMethod("getId");
Object getResult = m2.invoke(obj);
System.out.println(getResult);
}
※使用newInstance取得實體,然後再取得Class,這個Class可以讓setter/getter使用
※setter/getter公用方法
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("inheritate.Son");
Object obj = clazz.newInstance();
Class<?> cz = obj.getClass();
setXxx(cz, obj, "id", int.class, 1);
int rtn = (int) getXxx(cz, obj, "id");
System.out.println(rtn);
}
public static <T> void setXxx(Class<?> sourceClass, Object instance, String methodName, Class<T> parameterType, T value) throws Exception {
Method m = sourceClass.getMethod("set" + firstUpperCase(methodName), parameterType);
m.invoke(instance, value);
}
public static String firstUpperCase(String methodName) {
return methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
}
public static Object getXxx(Class<?> sourceClass, Object instance, String methodName) throws Exception {
Method m = sourceClass.getMethod("get" + firstUpperCase(methodName));
return m.invoke(instance);
}
※
沒有留言:
張貼留言