JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制,它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以我们形象的称之为:反射。
一、获取Class对象(类对象)
有三种方式:
Class<?> clazz = object.getClass();
Class<?> clazz = Student.class;
Class<?> clazz = Class.forName("xxx.Student"); //真实路径,带包名的类路径,包名.类名
//获取父类
Class superclass = clazz.getSuperclass();
二、创建实例
有两种方式:
//使用Class类的newInstance方法
Object object = clazz.newInstance();
Student object = (Student) clazz.newInstance();
//使用Constructor类(构造器)的newInstance方法
Constructor constructor = clazz.getConstructor();
Object object = constructor.newInstance();
//通过具有参数的构造函数创建类的实例
Constructor constructor = clazz.getConstructor(String.class, int.class);
Object object = constructor.newInstance("test", 66);
三、获取成员变量(属性/字段),并设置值
//获取所有字段
Field[] fieldArray = clazz.getFields(); //获取该类和父类公有的字段
Field[] declaredFieldArray = clazz.getDeclaredFields(); //获取该类所有(公有、受保护、私有)的字段;如果想要一起获取父类的字段,则superclass.getDeclaredFields(),然后放进去
//通过字段名获取对应字段
Field field = clazz.getDeclaredField(fieldName);
List<Field> fieldList = Arrays.stream(declaredFieldArray).collect(Collectors.toList());
for (Field field : fieldList) {
field.setAccessible(true);
String fieldName = field.getName(); //获取字段名
Object fieldValue = field.get(class); //获取字段值
field.set(class, newValue); //给该字段设置新值
//判断该字段是否有@MyAnnotation注解
if (field.isAnnotationPresent(MyAnnotation.class)) {}
}
//给该类新增字段
Field newField = new Field("newFieldName", String.class); //创建一个新的字段
clazz.add(newField); //向类中添加新的字段
四、获取方法,并调用方法
Class clazz = Class.forName("xxx.Student");
Object instance = clazz.newInstance();
//获取查询方法,然后执行查询方法,获取查询数据
Method method = instance.getClass().getMethod("selectAll"); //方法名
Object resultDataObj = method.invoke(instance); //执行方法
List resultDataList = (List) resultDataObj;
//获取插入方法,然后执行插入方法,插入数据
Method method = instance.getClass().getMethod("insert", Object.class); //如果该方法需要传递参数:方法名、参数类型
method.invoke(instance, "参数值");