java反射

本文深入探讨了Java运行时类型识别(RTTI)的工作原理,重点介绍了Class对象的作用及其实现机制,包括类的加载、链接和初始化过程,以及如何在运行时使用类型信息。

1、Class对象

  理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息。Class对象就是用来创建所有“常规”对象的,Java使用Class对象来执行RTTI,即使你正在执行的是类似类型转换这样的操作。

  每个类都会产生一个对应的Class对象,也就是保存在.class文件。所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类。Class对象仅在需要的时候才会加载,static初始化是在类加载时进行的。

 类加载器首先会检查这个类的Class对象是否已被加载过,如果尚未加载,默认的类加载器就会根据类名查找对应的.class文件。

  想在运行时使用类型信息,必须获取对象(比如类Base对象)的Class对象的引用,使用功能Class.forName(“Base”)可以实现该目的,或者使用base.class。注意,有一点很有趣,使用功能”.class”来创建Class对象的引用时,不会自动初始化该Class对象,使用forName()会自动初始化该Class对象。为了使用类而做的准备工作一般有以下3个步骤:

  • 加载:由类加载器完成,找到对应的字节码,创建一个Class对象
  • 链接:验证类中的字节码,为静态域分配空间
  • 初始化:如果该类有超类,则对其初始化,执行静态初始化器和静态初始化块
    @PostConstruct
      public void init() throws NoSuchFieldException {
        Field[] fields = this.getClass().getDeclaredFields();
        Arrays.asList(fields)
            .forEach(
                field -> {
                  Method[] methods = field.getType().getMethods();
                  Map<String, Method> methodMap = new ConcurrentHashMap<>();
                  Arrays.asList(methods)
                      .forEach(
                          method -> {
                            methodMap.put(method.getName(), method);
                          });
                  try {
                    field.setAccessible(true);
                    CLASS_METHODS.put(field.get(this), methodMap);
                  } catch (IllegalAccessException e) {
                    e.printStackTrace();
                  }
                });
      }

    上面的代码是填充一个map,map的每一个元素是这个类的成员变量,和这个变量的方法集合。

 

反射主要使用Class这个类的方法

 

 

 

补充资料:

 
七、关于Java类加载器内容的详解
     1、类的加载
            当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化
          ·加载:
               就是指将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象
          ·连接:
               验证:确保被加载类的正确性
               准备:负责为类的静态成员分配内存,并设置默认初始化值
               解析:将类中的符号引用替换为直接引用
          ·初始化:
               局部变量保存在栈区:必须手动初始化
               new 的对象保存在堆区:虚拟机会进行默认初始化,基本数据类型初始化值为0,引用类型初始化值为null
 
       2、类加载的时机(只加载一次)
             以下时机仅表示第一次的时候
             ① 创建类的实例的时候
             ② 访问类的静态变量的时候
             ③ 调用类的静态方法的时候
             ④ 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
             ⑤ 初始化某个类的子类的时候
             ⑥ 直接使用java.exe命令来运行某个主类
 
       3、类加载器
             负责将.class文件加载到内存中,并为之生成对应的Class对象
             虽然我们在开发过程中不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行
           
       4、类加载器的组成:
            ①Bootstrap ClassLoader 根类加载器
                  也被称为引导类加载器,负责Java核心类的加载,比如System类,在JDK中JRE的lib目录下rt.jar文件中的类
            ②Extension ClassLoader 扩展类加载器
                  负责JRE的扩展目录中jar包的加载,在JDK中JRE的lib目录下ext目录
            ③System ClassLoader 系统类加载器
                  负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径,主要是我们开发者自己写的类
 
        更多内容请参考《深入理解JVM虚拟机》
 

转载于:https://www.cnblogs.com/heroinss/p/10078854.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值