zoukankan      html  css  js  c++  java
  • java反射

    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虚拟机》
     
  • 相关阅读:
    Sql优化思路
    「网络流随想随记」
    「ZJOI 的部分题解整理」
    「循环矩阵相关的一些东西」
    知识蒸馏
    3D Human Pose Estimation with 2D Marginal Heatmaps
    模型剪枝
    目标检测小网络
    selenium---解决clear方法失效
    selenium---快速跳转到指定元素
  • 原文地址:https://www.cnblogs.com/heroinss/p/10078854.html
Copyright © 2011-2022 走看看