首先我们新建一个学生类:
package com.fanshe.student;
import java.util.Arrays;
import java.util.HashMap;
public class Student {
public String name;
public int age;
private String phone;
private HashMap<String, String> hobby;
private int[] address;
public String getName() {
return this.name;
}
private HashMap<String, String> getHobby() {
return this.hobby;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", phone=" + phone
+ ", hobby=" + hobby + ", address=" + Arrays.toString(address)
+ "]";
}
}
我们对这个学生类进行反射.....
加载类的三个方法:1.new Student().getClass();2.Class s=Student.class;3.Class.forName("com.fanshe.student.Student");
第一个都可以new了,也就不用反射了。第二个,要是可以点出来,先要导包吧?业务大了,动态怎么加载?难道先把所有包都导进去?第三个才是我们今天要讲的。
Class student = Class.forName("com.fanshe.student.Student");
通过类路径加载这个类。通过getDeclaredFields()方法获取属性(私有属性这个也可以的哦)。
Field[] res = student.getDeclaredFields();
for (Field field : res) {
String funname = field.getName();
System.out.println(funname + "-----" + field);
}
打印字段中属性名称看看。
Field name = student.getField("name");
Field hobby = student.getDeclaredField("hobby");
上面是获取类中的属性,接下来我们需要实例化一个类
Student obj = (Student) student.getConstructor().newInstance();
如果知道是什么类型的,直接强转一下。接下来用获取到的属性字段,set进入这个实例化的对象:
Student obj = (Student) student.getConstructor().newInstance();
name.set(obj, "小艾同学");
//hobby.setAccessible(true); //不设置或报错,没有权限
HashMap hobbymap = new HashMap();
hobbymap.put("zhuyao", "编程");
hobbymap.put("yeyu", "健身");
hobby.set(obj, hobbymap);
注意:私有属性,需要对属性设置hobby.setAccessible(true);(暴力访问)
设置暴力访问后:
--------------------以上就是对属性的反射-----------------------------------------------------
对方法的调用道理还是一样的,主要是方法用invoke()这个方法。第一个参数是调用的对象,往后是方法实体参数。
// 以下是对方法的调用,道理同理的,写法如下
Method getName=student.getDeclaredMethod("getName");
getName.setAccessible(true);
Object o=getName.invoke(obj);//方法返回值
System.out.println(o);
实体参数写法如下所示:
Method getName=student.getDeclaredMethod("getName",int.class,int.class,String.class);
getName.setAccessible(true);
Object o=getName.invoke(obj,1,2,"3");//方法返回值
System.out.println(o);