Java 反射以及动态代理,来看就懂了( 四 )


Java 反射以及动态代理,来看就懂了

文章插图
 
答:Method method = myClass.getDeclaredMethod("privateMd");
题目解析:此题主要考的是私有方法的获取,私有方法的获取并不是通过 getMethod() 方式,而是通过 getDeclaredMethod() 获取的 。
5.cglib 可以代理任何类这句话对吗?为什么?
答:这句话不完全对,因为 cglib 只能代理可以有子类的普通类,对于像最终类(final),cglib 是不能实现动态代理的,因为 cglib 的底层是通过继承代理类的子类来实现动态代理的,所以不能被继承类无法使用 cglib 。
6.JDK 原生动态代理和 cglib 有什么区别?
答:JDK 原生动态代理和 cglib 区别如下:
  • JDK 原生动态代理是基于接口实现的,不需要添加任何依赖,可以平滑的支持 JDK 版本的升级;
  • cglib 不需要实现接口,可以直接代理普通类,需要添加依赖包,性能更高 。
7.为什么 JDK 原生的动态代理必须要通过接口来完成?
答:这是由于 JDK 原生设计的原因,来看动态代理的实现方法 newProxyInstance() 的源码:
/** * ...... * @param   loader the class loader to define the proxy class * @param   interfaces the list of interfaces for the proxy class to implement * ...... */ @CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,                                      Class<?>[] interfaces,                                      InvocationHandler h)    throws IllegalArgumentException{// 省略其他代码
Java 反射以及动态代理,来看就懂了

文章插图
 
来看前两个参数的声明:
  • loader:为类加载器,也就是 target.getClass().getClassLoader()
  • interfaces:接口代理类的接口实现列表
看了上面的参数说明,我们就明白了,要使用 JDK 原生的动态只能通过实现接口来完成 。
总结通过本文可以知道 JDK 原生动态代理是使用反射实现的,但动态代理的实现方式不止有反射,还可以是 ASM(一个短小精悍的字节码操作框架)、cglib(基于 ASM)等 。其中 JDK 原生的动态代理是通过接口实现的,而 cglib 是通过子类实现的,因此 cglib 不能代理最终类(final) 。而反射不但可以反射调用静态方法,还可以反射调用普通方法和私有方法,其中调用私有方法时要设置 setAccessible 为 true 。




推荐阅读