Log4j Logger中的Obscure字段和修饰符

8
当查看org.apache.log4j.Logger类文件时,我们会发现它定义了一个类型为Class的合成字段,名称为class$org$apache$log4j$Logger
从字节码中可以看出,这个字段代表了自引用类,而当时常量池还不能引用类型。但是,我发现这个字段的修饰符很奇怪,它是0x41008,表示一个privatesynthetic字段(我可以跟踪),但是它还添加了一个0x40000的修饰符,在任何地方都找不到相关文档说明。
请问第19位的这个修饰符是从哪里来的?它表示什么?(Log4j编译为Java 1)。

不是常量池不能引用类型,而是ldc指令无法将这样的引用作为Class对象加载到操作数栈中。但是类常量池类型已经存在,允许指定thissuper类型,实现接口并声明所引用成员的类。 - Holger
1个回答

6

javap 可以完美地处理那个类文件:

  static java.lang.Class class$org$apache$log4j$Logger;
    descriptor: Ljava/lang/Class;
    flags: ACC_STATIC
    Synthetic: true

访问标志应该是u2,意思是两个字节的无符号数。看到0x41008比u2还大,有点困惑。一些工具会将access_flags存储在更大类型中,并注入辅助位(ASM这样做,JVM也这样做等等)。 我知道你正在使用ASM阅读,所以这可能是你正在查看的内容:
org/objectweb/asm/ClassReader.java:
        } else if ("Synthetic".equals(attrName)) {
            access |= Opcodes.ACC_SYNTHETIC
                    | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;

org/objectweb/asm/ClassWriter.java:

/**
 * Pseudo access flag to distinguish between the synthetic attribute and the
 * synthetic access flag.
 */
static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;

问题是,它是如何流传到您手中的...

2
使用IntelliJ的插件读取基于ASM而不是javap的字节码时会出现泄漏。应该依赖于官方工具。谢谢! - Rafael Winterhalter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接