反射的使用步骤(非常简单):
1.反射获取对象
1.1 调用无参构造方法(以Test类为例)
Class testClass = Class.forName("类的全路径");
Test test = (Test)testClass.newInstance();
1.2 调用有参的构造方法
例如:Test中有构造方法
public Test(int a, float b) {
this.a = a;
this.b = b;
}
Class testClass = Class.forName("类的全路径");
//有参构造方法必须要构造器
Class[] classes = new Class[]{int.class, float.class};//构造方法的参数类型
Constructor ctor = testClass.getConstructor(classes);
Object[] args = new Object[]{1, 1.5f}//构造方法的参数值
Test test = (Test)ctor.newInstance(args);
2.反射获取属性(例子同上)
2.1 Field[] fields = testClass.getFields();//获取所有公有属性
Field[] fields = testClass.getDeclaredFields();//获取所有属性(包括私有属性)
2.2 Field field = testClass.getField("属性名称");//获取单个属性
Field field = testClass.getDeclaredField("属性名称");//获取单个属性(包括私有属性)
field常用方法
Class typeClass = field.getType();//获取属性类型对应的Class对象,在操作javabean时非常有用
3.反射获取方法并执行
3.1 Method[] methods = testClass.getMethods();//获取所有公共方法
Method[] methods = testClass.getDeclaredMethods();//获取所有方法(包括私有方法)
3.2 Method method = testClass.getMethod(方法名,方法参数类型的class对象);
//执行
method.invoke(所属对象名,方法的参数值);
例如:
Test类中有方法
public void sing(String sing,int num){
System.out.println(sing);
System.out.println(num);
}
Method method = testClass.getMethod("sing", new Class[]{String.class, int.class});
method.invoke(test, new Object[]{"haha", 5});
4.WEB开发中需要注意的地方
在WEB开发中我们常常要获得表单中提交过来的数据,然后通过反射调用javabean的set方法,把数据存入javabean中,但由于表单提交上来的数据都是String类型,而javabean中肯定有不同的类型,这时,我们就需要通过封装类的构造方法来将String类型转化为相应的类型,例如:new Integer("5");但是,由于我们定义属性都是基本的数据类型,是没有构造方法的,这里就需要转化。
举例:(有两个类Student,Main)
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
//这里所要抛出的异常和导的包省略,只顺序把程序流程写完
public class Main() {
public static void main(String[] args) {
Class stuClass = Class.forName("Student");//注意这里是全路径,可能有包名
Student stu = stuClass.newInstance();//只有无参的构造方法,可以直接产生对象,不用产生构造器
Field[] fields = stuClass.getDeclaredFields();//获取所有的属性
for(Field field : fields) {//循环遍历
String fieldName = field.getName();//获取属性名称
Class typeClass = field.getType();//获取属性类型的Class对象
String setMethodName = "set" +
fieldName.substring(0, 1).toUpperCase() +
fieldName.substring(1);
Method method = stuClass.getMethod(setMethodName, typeClass);
或者(Method method = stuClass.getMethod(setMethodName, new Class[]{typeClass}); )
if(typeClass == int.class) {
typeClass = Integer.class;
}else if(typeClass == float.class) {
typeClass = Float.class;
}else if(typeClass == boolean.class) {
typeClass = Boolean.class;
}//....可以把所有的基础数据类型的Class对象都转化成封装类
//每个基础数据类型的封装类都有一个参数为String类型的构造方法,这里正是通过获得这个构造器
//来调用这个构造方法
Constructor ctor = typeClass.getConstructor(String.class);
//这里只是一个例子,这样的话就可以把1以各个属性的类型设置到相应的属性中
Object obj = ctor.newInstance(new Object[]{"1"});
method.invoke(stu, obj);//执行各个属性对应的set方法
或者(method.invoke(stu, new Object[]{obj}))
}
}
}
从上面可以看出,反射并不是想象的那么难,只要掌握了相应的API就没有什么难度了,但要想灵活的掌握应用就要付出很多的努力,这样才能写出大师级水平的程序。