反射
2022年1月2日大约 3 分钟
反射
反射
反射是 Java 中的一种机制,允许在运行时动态获取类的信息(如方法、属性等),并调用这些方法和属性。
反射的优点
- 动态获取类信息:可以在运行时获取类的结构信息,而无需在编译时确定。
- 动态创建对象:能够在运行时根据需要动态创建对象。
- 动态调用属性和方法:在运行时可以动态改变对象的行为。
反射的应用场景
- JDK 动态代理:通过反射中的
Method
类来调用指定的方法。 - Spring 注解处理:利用反射分析加注解的类,执行相应操作。
获取 Class
对象的四种方式
- 通过全类名
最常用的方法:
Class clazz1 = Class.forName("com.example.User");
- 类名.class 一般更多的是当参数进行传递
Class clazz2 = User.class;
- 对象.getClass
//有了这个对象时,才可以使用
User user = new User();
Class clazz3 = user.getClass();
System.out.println(clazz1==clazz2);
System.out.println(clazz1==clazz3);
- 通过类加载器xxxClassLoader.loadClass()传入类路径获取:
ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject");
通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执行。
反射可以获取到类的哪些信息?
- 获取构造方法:
//1,获取Class类
Class clazz = Student.class;
//-----------------------反射获取构造方法
//获取所有公共的构造方法
Constructor[] constructors = clazz.getConstructors();
//获取所有构造方法:(包括私有)
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
//获取单个构造方法(包括私有)
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
int modifiers = declaredConstructor.getModifiers();//获取构造方法修饰符的值
String name = declaredConstructor.getName();//获取构造方法的名字
Parameter[] parameters = declaredConstructor.getParameters();//获取构造方法形参
for (Parameter parameter : parameters) {
System.out.println("方法的形参:"+parameter);
}
//利用获取的构造方法创建对象
//因为此构造方法被private修饰,不具有权限,
//临时取消权限的校验,暴力反射
declaredConstructor.setAccessible(true);
Student student = (Student) declaredConstructor.newInstance("张三");
System.out.println(student);
- 获取成员变量
//获取公共修饰符修饰的成员变量 Field[] fields = clazz.getFields(); //获取所有的成员变量(包括私有) Field[] fields = clazz.getDeclaredFields(); //获取单个的成员变量 Field field = clazz.getDeclaredField("name"); //获取成员变量的权限修饰符 int modifiers = field.getModifiers(); //获取成员变量名 String name1 = field.getName(); //获取成员变量类型 Class<?> type = field.getType(); //获取成员变量记录的值 Student student = new Student("张三",23,"男"); //临时取消访问权限 field.setAccessible(true); Object o = field.get(student); System.out.println(o); //修改对象里面记录的值 field.set(student,"李四"); System.out.println(student);
- 获取成员方法
//获取Class类
Class clazz = Class.forName("com.tianji.myDemo3.Student");
//获取所有公共的成员方法(包含父类)
Method[] methods = clazz.getMethods();
//获取所有成员方法(包括私有)(不包括父类)
Method[] declaredMethods = clazz.getDeclaredMethods();
//获取单个成员方法
Method method = clazz.getDeclaredMethod("eat", String.class);
//获取方法的修饰符
int modifiers = method.getModifiers();
//获取方法的名字
String name = method.getName();
//获取方法的形参
Parameter[] parameters = method.getParameters();
//获取方法的返回值
Class<?> returnType = method.getReturnType();
//获取方法的抛出的异常
Class<?>[] exceptionTypes = method.getExceptionTypes();
//运行方法 invoke
Student s = new Student();
method.setAccessible(true); //临时取消访问权限
/**
* 参数一:表示方法的调用者
* 参数二:表示调用方法的时候传递的实际参数
*/
Object o = method.invoke(s, "米饭");
System.out.println(o);