概述
Java反射(Reflection)是Java编程语言的一个特性,它允许在运行时对类、接口、字段和方法进行动态查询和操作。反射提供了一种在运行时查看和修改程序行为的能力,这通常用于实现一些高级功能,如框架、ORM(对象关系映射)工具、IDE(集成开发环境)等。
1. 反射基础
1.1. 反射的用途
Java反射角度简单理解spring IOC容器-CSDN博客
1.2.获取class对象的三种方式
反射是基于class对象来操作的,获取class对象的三种方式如下:
- Class.forName("全类名") --> 对应类在源码阶段
/** 该方法最常使用* 由于编译时无法确定(运行时才能确认)该class object是一个什么类的对象,故而用?代替* 使用该方法,会立即触发类的初始化,类的静态初始化块会被执行。* 也就是静态代码块在new 实例化对象之前就已经加载了*/
Class<?> clazz = Class.forName("com.mycompany.myreflect.Student");System.out.println(clazz);
- 类名.class --> 对应类在加载阶段
/* 第二种方法一般是当做参数进行传递 * 如: synchronized(Student.class) */
Class<Student> clazz = Student.class; System.out.println(clazz);
- 对象.getClass --> 对应类在运行阶段
/*这种方法 当我们已经有这个类的对象时,才可以使用*/
Student s = new Student();Class<? extends Student> clazz = s.getClass();System.out.println(clazz);
更多理解可参考:Java 类加载和实例化对象的过程-CSDN博客
1.3. 反射的基本API
Java反射API主要位于java.lang.reflect包中,包括以下几个核心类:
- Class:表示类、接口、数组类、基本数据类型、以及void的Class对象。
- Field:表示类的成员变量(包括实例变量和类变量)。
Field[] fieldsType1 = clazz.getFields();//getFields 可以获得自己及父类(可以递归获得父类的父类的)的公共字段,不可以获得自己的或父类的私有字段for (Field field : fieldsType1){System.out.println(field);}System.out.println("------------------------------");// getDeclaredFields 可以获取自己的所有字段(私有和共有),但是不能获得父类的任何字段Field[] fieldsType2 = clazz.getDeclaredFields();for (Field field : fieldsType2){System.out.println(field);}System.out.println("------------------------------");// 获取父类的所有构造方法Field[] fieldsParentsAll = clazz.getSuperclass().getDeclaredFields();for (Field field : fieldsParentsAll){System.out.println(field);}
- Method:表示类的方法。
Method[] methods = clazz.getMethods();Method[] methods1 = clazz.getDeclaredMethods();Method method = clazz.getMethod("getName"); //获取特定方法,括号内是方法名,入参类型Method method1 = clazz.getMethod("functionA",String.class); //获取方法的修饰符对应的值 System.out.println("method modifiers:"+method.getModifiers()); //执行静态方法 method.invoke(null); //执行非静态方法 method1.invoke(student);
- Constructor:表示类的构造方法。
// 返回所有公共构造方法对象的数组 Constructor<?>[] constructors1 = clazz.getConstructors();// 返回所有构造方法对象的数组 Constructor<?>[] constructors2 = clazz.getDeclaredConstructors();// 返回单个特定公共构造方法对象,括号内的是该构造方法的参数类型Constructor<Student> constructor3 = (Constructor<Student>);// 返回单个特定构造方法对象,括号内的是该构造方法的参数类型Constructor<Student> constructor4 = (Constructor<Student>);
- Annotation: 获取注解
Annotation[] annotations = clazz.getAnnotations();Annotation[] annotations2 = clazz.getDeclaredAnnotations();Annotation annotation = clazz.getDeclaredAnnotation(MyAnnotation.class);Annotation annotation2 = clazz.getAnnotation(MyAnnotation.class);