反射怎么来的:
写个例子:1、先写一个StudentDemo类:
package com.weizhaoyang.Student;
public class StudentDemo{
private String username;
private Integer age;
private String sex;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
2、在创建一个TestStudent的类,当我们创建好两个类的时候:编辑器软件就已经编译成了.class文件,不去运行也会编译成.class文件,因为编辑器里面配置了jdk。
package com.weizhaoyang.Student;
public class TestStudent {
}
在eclipse这里勾上自动编译了。
3、创建StudentDemo的实例:当new的过程中,也就是运行期间,把上面的.class文件加载到java虚拟机上面,并且会得到一个Student类对应的类对象。
package com.weizhaoyang.Student;
public class TestStudent {
public static void main(String[] args) {
StudentDemo stu=new StudentDemo();
}
}
获取下类对象:这个student就是类对象。
//这个方法是Object中的方法
Class student=stu.getClass();
说下怎么判断.class文件被加载到java虚拟机上?通过在一个类上加上静态块。
这个静态块执行:这个StudentDemo.class文件首次被加载到java虚拟机上才会执行。
再次运行下主函数:运行的结果如下,这时这个类文件就被加载到了jvm上了。在运行的时候就相当于用java命令执行类文件。java运行期才会把.class文件加载到jvm上运行。
当我们不去new的时候,也会拿到类对象的,类对象也就是Class对象 。
这个类对象是由java虚拟机第一次加载字节码class文件的时候就自动的把这个对象创建了起来。
代码如下:
再证实下这个事实:代码如下,说明还没有new的时候这个类对象就已经加载到内存里面去了。class文件只是用的时候才会加载。new的时候才会分配内存。
总结:下面的图就是当一个类的主函数被压栈的时候,就可以拿到当前类的Class对象,从而把Student.class加载到jvm上,从而在内存中分配一块内存用来存储Class对象 ,而这个Class对象就可以获取到类里的成员变量,方法,和构造函数。
获取到类对象之后是不能操作类成员的,必须通过反射来操作,代码如下:
总结:平常是通过类的实例获取类的信息,而反射是通过类对象类获取类信息。
私有的方法通过反射的外部类来也可以去调用它。但是可以用匿名内部来保护类的安全。