Java 之反射机制

在Java中,不同的class分别由不同的ClassLoader负责加载,一个JVM默认的ClassLoader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader。

  • Bootstrap ClassLoader:负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等 。JVM级别的,一般是由C++撰写。
  • Extension ClassLoader:负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class。 继承自 Extension ClassLoader。
  • App ClassLoader:负责加载当前java应用的classpath中的所有类。继承自 Extension ClassLoader。
    Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。
    AppClassLoader的parent 是 ExtClassLoader,ExtClassLoader 的 parent 是null(因为Bootstrap ClassLoader是由C++编写的)

双亲委派原则
一个类加载器查找 class 和 resource 时,是通过“委托模式”进行的,它首先判断这个class是不是已经加载成功,看看缓存是否有,缓存有从缓存中获取,如果没有的话它并不是自己进行查找,而是先通过父加载器,然后递归下去,直到 Bootstrap ClassLoader,如果 Bootstrap classloader 找到了,直接返回,如果没有找到,则一级一级返回,最后到达自身去查找这些对象。这种机制就叫做双亲委托。
getDeclaredConstructor和getConstructor的区别

  • getDeclaredConstructor(Class < < <script type="math/tex" id="MathJax-Element-1048"><</script>? > > … parameterTypes)
    这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。getDeclaredConstructors()的返回结果就没有参数类型的过滤了
  • getConstructor(Class<? > > … parameterTypes)这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。getConstructors()的返回结果同样也没有参数类型的过滤。
    当我们通过 java 命令来运行某个类时,会经历如下的过程:
  • 类的加载由类加载器将指定的 class 文件,载入仅执行一 次。类加载后,就会创建一个对应的 Class 类的实例。
  • 链接 链接可以分为验证,准备与解析。验证用于验证之前所加载 class 文件结构上是否符合规范。准备阶段则为类结构分配相应的空间。解析则是把 class 文件中的符号引用替换为真实的实际引用。
  • 初始化为类的静态成员进行相应初始化赋值。

    ClassLoader 类加载器
    Java 使用 ClassLoader ClassLoader (子类)来实现的加载。 ClassLoader 调用 loadClass 方法来加载参数指定的类型。该会返回一个指定类型的 Class 对象。

Class
每个 类在加载后都会由系统创建一Class 对象, Class 对象存放类的相关信息,如方法变量构造器等。通过 Class 类的静态方法 forName 方法可以获取指定类型的 Class 对象。这与 ClassLoader 类的 loadClass 方法类似。不同的是, forName 默认是初始化类的。加载类默认是不初始化类的。
获取 Class Class 对象
可以通过下方式获取 Class 对象:

  • 通过 ClassLoader ClassLoader 对象的 loadClass loadClass 方法。 (Class<? > > )
  • 通过 Class 类的静态方法 forName 方法。 (Class<? > > )
  • 通过类名.class获取 。(Class<T > > )
  • 通过对象 .getClass 方法获取。 (Class<? extends T > > <script type="math/tex" id="MathJax-Element-1059">></script>)

创建对象

  • 通过 Class 对象的 newInstance 方法来创建对象。(类似于 调用无参的构造器)。
  • 如果要创建含有参数的构造器,需通过 Class 对象的 getConstructor getConstructor (只能获取 public 权限)或 getDeclaredConstructor 来获取相应的构造器对象 (Constructor ),然后通过构造器的 newInstance 方法创建对象。
    说明:可以调用 Constructor对象的 setAccessible 方法设置访问 权限。
    调用方法
    通过 Class 对象的 getMethod 或getDeclaredMethod 获取相关的 方法对象 Method ,然后通过 Method 对象的 invoke 方法调用。

访问成员变量
通过 Class 对象的 getField 或getDeclaredField 方法获取相关的成 员变量 Field 对象(域),然后通过 Field 对象的 set 与get 方 法设置与获取变量的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值