Java之反射
参考文档—-廖雪峰的Java教程
参考教学视频—-黑马Java进阶教程,轻松掌握Java反射原理
本文所有字节码文件对象都命名为cls,获取全部的是以数组的形式
概念
- 介绍:反射就是Reflection,Java的反射是指允许对字段(成员变量),成员方法和构造方法的信息进行编程访问
- 目的:反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法。
idea中的代码提示就是一种反射
- 获取
- 字段(成员变量)-获取修饰符、获取名字、获取类型、赋值/获取值
- 构造方法-获取修饰符、获取名字、获取形参、创建对象
- 成员方法-获取修饰符、获取名字、获取形参、获取返回值、抛出的异常、获取注解、运行方法
获取Class对象
- 直接通过一个
Class的静态变量class获取:一般更多时当作参数进行传递
1 | Class cls = String.class; |
- 如果我们有一个实例变量,可以通过该实例变量提供的
getClass()方法获取:当我们已经有这个类对象才使用
1 | String s = "Hello"; |
- 如果知道一个
class的完整类名,可以通过静态方法Class.forName()获取:最常用的
1 | Class cls = Class.forName("全类名"); |
反射获取构造方法
- 获取构造方法
获取单个的时候保持字节码和构造方法中的参数一一对应
1 | Constructor cons = cls.getConstructor(???.class);//获取某个`public`的`Constructor`; |
- 用法:
newInstance(Object... parameters)用法具体见暴力反射
反射获取成员变量
- 获取成员变量
1 | Field field = cls.getField(String name);//根据字段名获取某个public的field(包括父类) |
- 修改
1 | // 运行上述代码,打印的name字段从Xiao Ming变成了Xiao Hong,说明通过反射可以直接修改字段的值。 |
- 用法:
getName(),getType(),getModifiers()具体参考成员方法的用法
反射获取成员方法
- 获取方法
1 | Method method = cls.getMethod(name,???.class);//获取某个public的Method(包括父类) |
- 用法
- 获取修饰符
1
int modifiers = method.getModifiers();
- 获取名字
1
String name = method.getName();
- 获取形参
1
Parameter[] parameters = method.getParameters();
- 获取返回值
1
2
3
4```
- 获取抛出的异常
```java
Class[] exceptionTypes = method.getExcptionTypes();
- 方法运行->Student默认是已经创建好的类,eat是其中的private成员方法
1
2
3
4Student s = new Student();
method.setAccessible(true);
method.invoke(s,"含八嘎");
Obkect result =method.invoke(s,"含八嘎");//如果有返回值
暴力反射
eg,获取的学生构造函数是private修饰的,此处以构造方法为案例
1
2
3
4 Constructor con = cls.getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);//临时取消权限校验
Student stu = (Student) con.newInstance("zhangsan",23);
System.out.println(stu);
动态代理
分析
- 特点:无侵入式的给代码添加额外的功能
- 如何保证代理:通过接口,后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法
实现
1 | import java.lang.reflect.InvocationHandler; |
- 定义一个InvocationHandler实例,它负责实现接口的方法调用;
- 通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:
- 使用的ClassLoader,通常就是接口类的ClassLoader;
- 需要实现的接口数组,至少需要传入一个接口进去;
- 用来处理接口方法调用的InvocationHandler实例。
- 将返回的Object强制转型为接口。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Blog of Sof!
评论






