当我们为某个项目配置好jdk后,java文件在进行编译时,javac就已经将对应的Java文件编译为class文件了。在java中创建这个类的对象时且该类是首次被加载时,jvm虚拟机就加载对应的class文件并在内存中(方法区)创建了这个类对象并拷贝这个class文件中所有的成员变量到这个class类对象。
之后在堆内存中开辟一块内存空间用于存储这个类的对象并拷贝一份属性,栈中存放的是堆中对应的类的对象的内存地址。过程见下图:
反射:通过创建对象实例加载class文件到jvm上面时创建的Class对象来获取这个类中的成员变量。其实就是平时我们获取这个类的信息是通过实例这个类来获取,而反射就是通过class类对象来获取信息
我们以代码为例:
先创建一个用于反射的对象类:
public class Student {
public Student(){
System.out.println("无参构造");
}
public Student(int i){
System.out.println("一个参数构造函数");
}
private Student(int i,String name){
System.out.println("两个参数构造函数");
}
private String name;
private String sex;
private String age;
public Date bir;
public Date getBir() {
return bir;
}
public void setBir(Date bir) {
this.bir = bir;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
private String getAge() {
return age;
}
private void setAge(String age) {
this.age = age;
}
}
反射操作:
public class test {
@Test//通过反射获取成员变量
public void reflectForBianliang() throws Exception{
//我们是可以通过反射来获取或者设置类对象中的变量的
//创建一个类对象
Class cla=Student.class;
//创建用类对象创建一个实例对象(这个方法会调用无参构造)
//此处可以引出一个问题,就是为什么类中必须有一个无参构造函数,就是因为newInstance()方法实例化时调用的就是无参构造。
Object obj=cla.newInstance();
//获取类对象中的某个变量
Field fie=cla.getDeclaredField("age");
//开启权限,否则无法设置私有变量
fie.setAccessible(true);
//赋值
fie.set(obj, "18");
//取值
Object value=fie.get(obj);
System.out.println(value);
}
@Test
public void reflectForfangfa() throws Exception{
//通过反射可以调用方法
Class cla=Student.class;
Object obj=cla.newInstance();
//获取类对象中的某个方法(getAge)
Method method=cla.getDeclaredMethod("setAge", String.class);
//因为是私有的所以开启权限才可以调用
method.setAccessible(true);
method.invoke(obj, "18");
//获取类中的getAge方法
Method method2=cla.getDeclaredMethod("getAge");
method2.setAccessible(true);
Object obj2=method2.invoke(obj);
System.out.println(obj2);
}
}
以上有什么疏漏或者错误,欢迎各位批评指正。
原文:https://www.cnblogs.com/keyforknowledge/p/10223669.html