• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
月迷津
博客园    首页    新随笔    联系   管理    订阅  订阅

类加载器和反射

一、反射

  概述

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

  三种获取Class对象的方式

    1:Person p = new Person();
    Class c = p.getClass();

    2:Class c2 = Person.class;
    任意数据类型都具备一个class静态属性,看上去要比第一种方式简单.

    3:将类名作为字符串传递给Class类中的静态方法forName即可
    Class c3 = Class.forName("Person");

    4:第三种和前两种的区别
      前两种你必须明确Person类型.
      后面是你是这种类型的字符串就行.这种扩展更强.我不需要知道你的类.我只提供字符串,按照配置文件加载就可以了

  通过反射获取构造方法并使用

    获取构造方法
      getConstructors
      getDeclaredConstructors
    创建对象
      newInstance()
      con.newInstance(“zhangsan", 20);

  通过反射获取成员变量并使用

    获取所有成员
      getFields,getDeclaredFields
    获取单个成员
      getField,getDeclaredField
    修改成员的值
      set(Object obj,Object value)   将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

  通过反射获取成员方法并使用

    获取所有方法
      getMethods
      getDeclaredMethods
    获取单个方法
      getMethod
      getDeclaredMethod
    暴力访问
      method.setAccessible(true);

二、动态代理

    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
    动态代理:在程序运行过程中产生的这个对象
    而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

    在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
    Proxy类中的方法创建动态代理类对象
      public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
    最终会调用InvocationHandler的方法
      InvocationHandler
      Object invoke(Object proxy,Method method,Object[] args)

    Proxy类中创建动态代理对象的方法的三个参数;
      ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
      Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
      InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

    每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的invoke 方法来进行调用。

    InvocationHandler接口中invoke方法的三个参数:
      proxy:代表动态代理对象
      method:代表正在执行的方法
      args:代表调用目标方法时传入的实参

    Proxy.newProxyInstance
      创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,
      也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,
      以$开头,proxy为中,最后一个数字表示对象的标号。
    System.out.println(u.getClass().getName());

posted @ 2018-10-10 09:29  月迷津  阅读(354)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3