反射详细理解
一。反射reflection定义:
java中,反射机制是在运行状态中,对于任意一个类,都能够知道这个类的属行和方法,对于任意一个对象,都能够调用它的任一方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
二。反射reflection的工作机制:
程序运行时,java系统会一直对所有对象进行所谓的运行时类型识别,这项信息记录了每个对象所属的类。通过专门的类可以访问这些信息。用来保存这些信息的类是Class类,Class类为编写可动态操纵的java代码提供了强大的功能。
编写代码步骤
首先写一个Student类供下面使用:
package reflex;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void study(String what){
System.out.println("学"+what);
}
}
1.构造Class类对象的三种方式、
//创建Student的Class对象
//第一种方法:通过类的地址获得:语法:Class.forName("路径名")
Class c1 = Class.forName("reflex.Student");//class reflex.Student
//第二种方法:通过被反射类的实例对象
Student s = new Student();
Class c2 = s.getClass();//class reflex.Student
//第三种方法:类名.class
Class c3 = Student.class;//class reflex.Student
2.获取构造方法
//先得到Class对象
Class sc = Student.class;
//1.调用它的无参构造方法。Class对象.getContructor();
Constructor c1 = sc.getConstructor();
//2.调用它的有参构造方法Class对象.getContructor(参数数据类型类型的类);
Constructor c2 = sc.getConstructor(String.class, int.class);
//3.得到所有的构造函数:Class对象.getConstructors();返回的是构造方法的数组,需要遍历得出结果。
Constructor[] c3 = sc.getConstructors();
for (Constructor c4:c3
) {
System.out.println(c4);
}
3.获取实例化对象
//获取实例化对象
//首先第一步还是得到class对象
Class<Student> sc = Student.class;
//通过class对象得到构造方法
//无参构造方法
Constructor<Student> c = sc.getConstructor();
//无参实例对象.newInstance()
Student s1 = c.newInstance();
//通过构造方法得到的对象创建实例对象:.newInstance(参数类型的类)
Constructor<Student> constructor = sc.getConstructor(String.class, int.class);
Student student = constructor.newInstance("小明", 10);
//注:如果Student生成了set和get和toString方法。这样对属行设置获得操作更加方便
4.获得字段名(属性)
//获得字段
//第一步获得Class对象
Class<Student> sc = Student.class;
//第二步获得无参构造方法
Constructor<Student> constructor = sc.getConstructor();
//第三部获得实例化对象
Student s1 = constructor.newInstance();
//第四步获得字段对象:getField()获得公共字段,getDeclaredField()啥都能获得,getFields()返回的是所有字段的数组。
//括号里填属性名
Field nameField = sc.getDeclaredField("name");
//除了pubic修饰的的可以直接访问,其他的这里都会出现异常,所以需要调用nameField.setAccessible(true);强制访问
nameField.setAccessible(true);
//设置字段值
nameField.set(s1,"k");
//获得字段值的方法:get()
System.out.println( nameField.get(s1)); //k
5.获取普通方法
//获取普通方法
//创建Class类对象
Class<Student> studentClass = Student.class;
//获得构造方法的对象
Constructor<Student> constructor = studentClass.getConstructor();
//获得实例对象
Student s1 = constructor.newInstance();
//获得普通方法,括号里填:方法名,参数类型的类
Method study = studentClass.getDeclaredMethod("study", String.class);
// Method studyMethod = studentClass.getMethod("study", String.class);
//如果报不让访问的异常就强制访问
study.setAccessible(true);
//study方法被调用:方法名.invoke(实例化对象,传参数值)
Student o =(Student) study.invoke(s1, "数学");
System.out.println(o);//学数学