首先在JAVA中,我们可以分为三个阶段。
1.源代码阶段
源代码也即.java 文件,经过javac编译得到字节码文件.class
而字节码文件经过类加载器(ClassLoader)将其加载到内存中
2.类对象阶段
类对象中就会有之前定义的成员变量,成员方法和构造方法。
成员变量被放在Field[] 数组中
成员方法被放在Method[] 数组中
构造方法被放在Constructor[] 数组中
3.运行时阶段
当类对象被创建以后,就会处在运行时过程中。
获取Class对象的三种方法
1.直接利用全类名Class.forName(“全类名”)方法获取
2.利用类的属性***.class获取
3.利用对象的方法xxx.getClass()获取
获取Class中的成员变量,成员方法,构造方法的方法:
其中:
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
同样类似的还有getConstructors()和getDeclaredConstructors()、getMethods()和getDeclaredMethods(),这两者分别表示获取某个类的方法、构造函数。
以下为Demo示例(Idea实现):
首先创建一个Pojo类,此处示例为Student
public class Student {
private String name;
private int id;
private int age;
private double money;
public Student(String name, int id, int age, double money) {
this.name = name;
this.id = id;
this.age = age;
this.money = money;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
", money=" + money +
'}';
}
public void readBook(){
System.out.println("读书");
}
public void readBook(String bookName){
System.out.println("读"+bookName);
}
}
之后写一个Demo测试三种方法:
第一种方法:
Class cls = Class.forName("com.wl.nuaa.pojo.Student");
Method[] methods = cls.getMethods();
for(Method method : methods){
System.out.println(method);
}
第二种方法:
Class cls = Student.class;
Field[] fields = cls.getDeclaredFields();
for (Field field : fields){
System.out.println(field);
}
第三种方法:
Student student = new Student();
Class cls = student.getClass();
Constructor[] constructors = cls.getConstructors();
for (Constructor constructor:constructors){
System.out.println(constructor);
}
一个反射的案例:
为了解耦,我们利用一个配置文件来操作,让程序根据配置文件给出的数据对进行输出任意类的任意方法。
配置文件内容:
classname=com.wl.nuaa.pojo.Student
methodname=readBook
配置文件与com同级
这里利用一个Demo实现:
Properties properties = new Properties();
ClassLoader classLoader = ReflectDemo.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
properties.load(is);
String className = properties.getProperty("classname");
String methodName = properties.getProperty("methodname");
Class cls = Class.forName(className);
Object obj = cls.getDeclaredConstructor().newInstance();
Method method = cls.getDeclaredMethod(methodName);
method.invoke(obj);
首先需要一个属性文件的对象实例,要利用到类加载器将属性文件加载进来
之后利用className和methodName存放在配置文件中配置的数据值
下面就是利用获取类对象的第一种方法,得到其对象实例,和成员方法,之后利用invoke()实现方法。
在拥有了配置文件以后,如果系统上线,便无需修改代码导致系统重新测试,评估,上线,只需修改配置文件即可达到系统配置修改的目的。