3.5 . 反射的进一步应用(理解)
3.5 .1 通过反射调用类中的方法
在正常情况下是通过对象.方法()的形式调用类中的指定方法,那么实际上可以通过反射机制完成类中方法 的调用.
在Class类中使用以下的方法取得要调用方法的Method对象
public Method getMethod(String name,
Class... parameterTypes)
throws NoSuchMethodException,
SecurityException
取得Method对象之后, 通过如下方法调用:
public Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
说明: 以上代码表示程序要真正执行的方法.
package org.lxh.demo.classdemo04;
import java.lang.reflect.Method;
public class GetConstructorDemo01 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo05.Person");
//本程序 中将调用Person类的sayHello方法
Method met = c.getMethod("sayHello");
met.invoke(c.newInstance());
}
}
以上的调用了类中无参数,无返回值的方法
范例: 调用有返回值的方法:getInfo()
package org.lxh.demo.classdemo05;
import java.lang.reflect.Method;
public class InvokeMethodDemo02 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo05.Person");
//本程序 中将调用Person类的getInfo方法
Method met = c.getMethod("getInfo");
String val = (String)met.invoke(c.newInstance());
System.out.println(val);
}
}
继续使用以上的操作,调用Person类别的say()方法, 此方法有参数和返回值.
代码出错: 未指定传递的参数
更正:
3.5.2 通过反射调用类中的getter 及 setter
类中在定义的时候就已经明确的声明的GETTER和SETTER 方法, 这样做的目的,就是为了反射操作的方便.
package org.lxh.demo.classdemo05;
import java.lang.reflect.Method;
public class InvokeMethodDemo04 {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo05.Person");
Object obj = c.newInstance();
set("name","Luck",obj,String.class);//将当前对象obj中的"参数1"属性赋值给"参数2"
set("age",30, obj,int.class);
System.out.println(obj);
get("name", obj);
get("age", obj);
}
/*
* @param name 属性名称
* @param value 属性值
* @param obj 要操作的对象
*/
public static void set(String name,Object value,Object obj,Class<?> type) throws Exception{
Method met = obj.getClass().getMethod("set"+initStr(name),type);
met.invoke(obj,value);//调用方法
}
public static void get(String name,Object obj) throws Exception{
Method met = obj.getClass().getMethod("get"+initStr(name));//初始化需要调用的方法
Object value = met.invoke(obj);// 开始调用
System.out.println(value);
}
public static String initStr(String name){
StringBuffer buf = new StringBuffer();
buf.append(name.substring(0,1).toUpperCase()).append(name.substring(1));
return buf.toString();
}
}
以上的操作原理在以后的学习中会经常出现, 常规开发中一般不会应用到.
3.5.3 通过反射调用类中的getter 及 setter
在反射机制中,不光可以操作方法,还可以直接操作类中的属性.
package org.lxh.demo.classdemo05;
import java.lang.reflect.Field;
public class InvokeFieldDemo {
public static void main(String[] args) throws Exception{
Class<?> c = Class.forName("org.lxh.demo.classdemo05.Person");
Object obj = c.newInstance();
//Field nameField = c.getField("name");
Field nameField = c.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(obj, "Michele");
System.out.println(nameField.get(obj));
}
}
类中的属性可以通过代码设置访问权限, 但会有安全方面的问题, 谨慎使用.