反射
1、概念
- 反射是指在运行时,获取类的信息,创建对象,获取属性,调用方法的一个过程。
2、获取Class类的三种方式
2.1、通过类获取
- 方式是:Student.class获取类的字节码对象。
- 代码
@Test
public void test01(){
Class<Student> clss = Student.class;
}
2.2、通过对象获取
@Test
public void test02(){
Student student = new Student();
Class<? extends Student> clss = student.getClass();
}
2.3、通过Class静态方法获取
@Test
public void test03() throws ClassNotFoundException {
Class<?> clss = Class.forName("com.yan.entity.Student");
}
3、获取构造方法
- 获取所有公共构造方法
- 获取所有构造方法,包括私有
- 获取制定参数类型的构造方法
@Test
public void test03() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Constructor<?>[] constructors = clss.getConstructors();
Constructor<?>[] declaredConstructors = clss.getDeclaredConstructors();
Constructor<?> constructor = clss.getDeclaredConstructor(Integer.class, String.class, String.class);
}
4、反射创建对象的过程
4.1、过程
- 第一步,创建字节码对象
- 第二步,获取构造方法
- 第三步,构造方法设置setAccessible(true)
- 第四步,通过newInstance(…)传值创建对象。
- 注意实体类的字段类型使用使用包装类型。
4.2、代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String name;
}
@Test
public void test04() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Constructor<?> constructor = clss.getDeclaredConstructor(Integer.class, String.class);
constructor.setAccessible(true);
Object obj = constructor.newInstance(1, "zhangsan");
System.out.println(obj);
}
5、获取字段
5.1、获取字段方式
@Test
public void test05() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Field[] fields = clss.getFields();
Field[] declaredFields = clss.getDeclaredFields();
Field name = clss.getDeclaredField("name");
}
5.2、给字段赋值
@Test
public void test06() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Constructor<?> constructor = clss.getDeclaredConstructor();
constructor.setAccessible(true);
Object obj = constructor.newInstance();
Field nameFile = clss.getDeclaredField("name");
nameFile.setAccessible(true);
nameFile.set(obj,"zhangsan");
System.out.println(nameFile.get(obj));
}
6、获取方法
6.1、获取方法的方式
- 获取所有公共方法
- 获取所有方法,包括私有,不包括继承。
- 获取指定方法
@Test
public void test07() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Method[] methods = clss.getMethods();
Method[] declaredMethods = clss.getDeclaredMethods();
Method getName = clss.getDeclaredMethod("getName");
}
6.2、调用方法
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String name;
public Student(String name) {
this.name = name;
}
public Student(Integer id) {
this.id = id;
}
public void show(String something) {
System.out.println("调用show方法,执行" + something);
}
}
@Test
public void test08() throws Exception {
Class<?> clss = Class.forName("com.yan.entity.Student");
Constructor<?> constructor = clss.getDeclaredConstructor(Integer.class, String.class);
constructor.setAccessible(true);
Object obj = constructor.newInstance(1, "zhangsan");
Method showMethod = clss.getDeclaredMethod("show", String.class);
showMethod.setAccessible(true);
showMethod.invoke(obj,"看电视指令");
}