• Javassist-ConstPool常量池


    什么是常量池

    引用关于JVM 7规范的第4.4节

    Java virtual machine instructions do not rely on the runtime layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pool table

    大致意思:Java虚拟机指令不依赖于类、接口、类实例或数组的运行时布局。相反,指令引用 constant_pool 表中的符号信息。

    所以,当我们创建属性相关实例时,都需要参数 constant_pool

    如何获取常量池

    方式一:通过ClassFile

    ClassPool pool = ClassPool.getDefault();
     //获取实体类
    CtClass ctClass = pool.get(obj.getClass().getName());
    ConstPool constPool = ctClass.getClassFile().getConstPool();
    
    • 1
    • 2
    • 3
    • 4

    方式二:通过FieldInfo

    ClassPool pool = ClassPool.getDefault();
    //获取实体类
    CtClass ctClass = pool.get(obj.getClass().getName());
    //获取属性
    CtField ctField = ctClass.getField(FieldName);
    //获取属性字段信息
    FieldInfo fieldInfo = ctField.getFieldInfo();
    //获取常量池
    ConstPool constPool = fieldInfo.getConstPool();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方式三:通过MethodInfo

    ClassPool pool = ClassPool.getDefault();
    //获取实体类
    CtClass ctClass = pool.get(obj.getClass().getName());
    //获取方法
    CtMethod ctMethod = ctClass.getDeclaredMethod("foo","ceshi");
    //获取方法信息
    MethodInfo methodInfo = ctMethod.getMethodInfo();
    //获取常量池
    ConstPool constPool = methodInfo.getConstPool();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    测试:

    System.out.println("ConstPool=" + ctClass.getClassFile().getConstPool());
    System.out.println("ConstPool=" + ctClass.getField(FieldName).getFieldInfo().getConstPool());
    System.out.println("ConstPool=" + ctClass.getDeclaredMethod("foo").getMethodInfo().getConstPool());
    
    if (fieldInfo.getConstPool().equals(ctClass.getClassFile().getConstPool())) {
        System.out.println("true");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出:

    ConstPool=javassist.bytecode.ConstPool@7a07c5b4
    ConstPool=javassist.bytecode.ConstPool@7a07c5b4
    ConstPool=javassist.bytecode.ConstPool@7a07c5b4
    true
    
    • 1
    • 2
    • 3
    • 4

    测试发现,三种方式获取的 ConstPool 是一样的。每个Java类都有一个常量池,使用常量池需要注意:

    • 在Javassist中,CtClass中的常量池字段是一个实例字段,这意味着如果您有两个 CtClass 对象代表同一个类,您将有两个不同的常量池实例(即使它们代表实际类文件中的常量池)。修改 CtClass 实例之一时,必须使用相关联的常量池实例,以具有预期的行为。
    • 有时您可能没有 CtClass 而是 CtMethod 或 CtField,这不允许您回溯到CtClass实例,在这种情况下,可以使用ctMethod.getMethodInfo().getConstPool()ctField.getFieldInfo().getConstPool() 获取常量池。
  • 相关阅读:
    MySQL用户管理(CentOS)
    数据可视化【原创】vue+arcgis+threejs 实现立体光圈闪烁效果
    百度测开初面面试题分享
    速卖通数据分析怎么看?速卖通数据分析工具有哪些?—站斧浏览器
    【ETL工具】Datax-ETL-SqlServerToHDFS
    Flask学习(二):flask模板渲染
    在ubuntu20.04 上配置 qemu/kvm linux kernel调试环境
    与 Python 之父聊天:更快的 Python
    Ceph入门到精通-sysctl.conf 配置
    5G 3GPP全球频谱介绍
  • 原文地址:https://blog.csdn.net/weixin_40017062/article/details/126477135