• 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() 获取常量池。
  • 相关阅读:
    已解决java.beans.IntrospectionException: 在Java Beans中内省过程失败的正确解决方法,亲测有效!!!
    C语言选择排序
    创客匠人工具助力教培机构快速适应线上教学
    大数据数据压缩和企业优化
    深度学习:循环神经网络RNN及LSTM
    6.云原生-KubeSphere3.3.0安装MYSQL
    拦截|篡改|伪造.NET类库中不限于public的类和方法
    MobTech短信验证ApiCloud SDK
    好用的 WAF 工具(SafeLine)
    多线程JUC 第2季 ReentranctLock实现加锁和解锁过程
  • 原文地址:https://blog.csdn.net/weixin_40017062/article/details/126477135