反射机制与动态代理

左手的ㄟ右手 2022-04-14 06:53 352阅读 0赞

以前学习基础的时候不知道哪些是重点,也不会注意,自己动手少,用的少,自然也不会知道,就落下了知识点,当被问反射机制起来时,听过,但怎么说,到底是怎么一回事,脑子一片空白,答不上来,也觉得惭愧。

一.什么是反射机制?

在运行期中,对于任意一个类,都能够调用某一个类的属性与方法,或者对与一个对象,任意的对象都能调用这个对象的属性和方法,这个类或对象相对其他类或对象像是透明的。这种动态的调用其他类或者对象的属性和方法就叫做反射机制,JAVA反射机制:”程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言“,这样说你可能会感觉模模糊糊的,不太懂。

反射机制通过或者某个类或对象的字节码文件对象(.class),这是必须的,通过字节码对象就能获取该类的属性和方法,

获取字节码文件对象的三种方式,针对不同情况下选择合理的使用

1、

源码阶段,并没有变成字节码文件

  1. //创建源码期的字节码文件对象,参数为类的路径即包名+类名,相对路径即类名
  2. Class a = Class.forName("A");
  3. //创建实例对象
  4. A a1 = (A)a.newInstance();

2、

编译期后字节码阶段

  1. //创建编译期的字节码文件对象
  2. Class a = A.class;

3、

创建对象阶段

  1. //创建对象
  2. A as = new A();
  3. //创建对象期的字节码文件对象
  4. Class a = as.getClass();

通过反射机制过去的字节码文件对象能干嘛?

假设已存在A类

1.创建实际对象

  1. //创建编译期的字节码文件对象
  2. Class a = A.class;
  3. //创建实例对象
  4. A a1 = (A)a.newInstance();

2.获取该类的构造器

  1. //创建编译期的字节码文件对象
  2. Class a = A.class;
  3. //通过字节码对象获取无参构造器,通过构造器创建实例对象
  4. Constructor constructor = a.getConstructor();
  5. A a2 =(A)constructor.newInstance();
  6. //带参构造器
  7. Constructor constructor1 = a.getConstructor(String.class);
  8. System.out.println("初始化带参构造器");
  9. A a3 = (A)constructor1.newInstance("削功名");

3.获取该类的属性并输出

  1. //创建实例对象
  2. Class a = A.class;
  3. A a1 = (A)a.newInstance();
  4. //调用该类的属性,形参传入属性名
  5. Field field = a.getDeclaredField("name");
  6. //及那个私有的属性打开权限
  7. field.setAccessible(true);
  8. //get方法参数传入该类的实例对象
  9. System.out.println(field.get(a1));

4.获取该类的方法并执行

  1. //创建编译期的字节码文件对象
  2. Class a = A.class;
  3. //创建实例对象
  4. A a1 = (A)a.newInstance();
  5. //调用该类方法(参数为该类的方法名)
  6. Method method = a.getMethod("hello");
  7. //参数传入一个实例参数
  8. method.invoke(a1);

二.动态代理

1.什么是动态代理?

动态代理是一种设计模式,可以这么理解,比如自己需要买一瓶水,自己不想动,叫人帮买一瓶水。这个代理对象是在程序运行过程中创建的,这个我们反射机制一样在程序运行过程中来实例化对象、调用方法等操作。

创建代理对象需要使用 ava.lang.reflect下的 Proxy 类 和 InvocationHandler 接口; JDK提供的代理只能针对接口做代理,这意味着我们返回的必须是一个接口对象。更强的代理通过Proxy的newProxyInstance()方法创建动态代理对象。

1、创建一个接口,在接口中写个方法

  1. public interface A {
  2. void buy();
  3. }

2.创建一个InvocationHandle 代理对象

  1. public class B implements InvocationHandler {
  2. private Object target;
  3. public B(Object a){
  4. this.target = a;
  5. }
  6. @Override
  7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  8. method.invoke(target,args);
  9. System.out.print("代理对象: 某某");
  10. return null;
  11. }
  12. }

3.创建一个实例类,并通过代理执行

  1. public class C implements A {
  2. @Override
  3. public void buy() {
  4. System.out.println("买水");
  5. }
  6. public static void main(String[] args) {
  7. C a = new C() ;
  8. //本身来做
  9. a.buy();
  10. System.out.println("----------------");
  11. //传入一个实例对象
  12. B b = new B(a);
  13. /**
  14. * JDK提供的接口只能针对接口做代理。因此返回必须是个接口
  15. * 参数为 实例对象的类加载器,类实现的所有接口的对象,代理对象
  16. */
  17. A aa = (A)Proxy.newProxyInstance(a.getClass().getClassLoader(),a.getClass().getInterfaces(),b);
  18. //代理来做
  19. aa.buy();
  20. }
  21. }

发表评论

表情:
评论列表 (有 0 条评论,352人围观)

还没有评论,来说两句吧...

相关阅读

    相关 反射动态代理

    实例说明   代理是Java SE 1.3版新增的特性。使用代理可以在程序运行时创建一个实现指定接口的新类。通常只有在编译时无法确定需要使用哪个接口时才需要使用代理,这

    相关 Java反射动态代理

          与[javax.lang.model][] 不同的是,通过反射API可以获取程序在运行时刻的内部结构。反射API中提供的动态代理也是非常强大的功能,可以原生实现[A

    相关 反射机制动态代理

    以前学习基础的时候不知道哪些是重点,也不会注意,自己动手少,用的少,自然也不会知道,就落下了知识点,当被问反射机制起来时,听过,但怎么说,到底是怎么一回事,脑子一片空白,答不上