Java Log4j记录器中的模糊字段和修饰符

Java Log4j记录器中的模糊字段和修饰符,java,bytecode,Java,Bytecode,当查看org.apache.log4j.Logger的类文件时,它定义了一个名为class$org$apache$log4j$Logger的类型为class的合成字段 从字节码看,很明显,这个字段表示自引用类,而常量池还不能引用类型。然而,我觉得奇怪的是这个字段的修饰符是0x41008,它表示一个private,synthetic字段(我可以遵循),但它添加了一个修饰符0x40000,我在任何地方都找不到 第19位的修饰符来自何处,它表示什么?(Log4j是为Java 1编译的)。javap对该

当查看
org.apache.log4j.Logger
的类文件时,它定义了一个名为
class$org$apache$log4j$Logger
的类型为
class
的合成字段

从字节码看,很明显,这个字段表示自引用类,而常量池还不能引用类型。然而,我觉得奇怪的是这个字段的修饰符是
0x41008
,它表示一个
private
synthetic
字段(我可以遵循),但它添加了一个修饰符
0x40000
,我在任何地方都找不到

第19位的修饰符来自何处,它表示什么?(Log4j是为Java 1编译的)。

javap对该类文件非常满意:

  static java.lang.Class class$org$apache$log4j$Logger;
    descriptor: Ljava/lang/Class;
    flags: ACC_STATIC
    Synthetic: true
access_标志应为
u2
,表示2字节无符号。令人费解的是看到
0x41008
,它比
u2
大。众所周知,有些工具以较大的类型存储访问标志,并注入辅助位(ASM执行,JVM执行,等等)。我知道您正在使用ASM阅读,所以这可能就是您所看到的:

org/objectweb/asm/ClassReader.java:

        } else if ("Synthetic".equals(attrName)) {
            access |= Opcodes.ACC_SYNTHETIC
                    | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
/**
 * Pseudo access flag to distinguish between the synthetic attribute and the
 * synthetic access flag.
 */
static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
org/objectweb/asm/ClassWriter.java:

        } else if ("Synthetic".equals(attrName)) {
            access |= Opcodes.ACC_SYNTHETIC
                    | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
/**
 * Pseudo access flag to distinguish between the synthetic attribute and the
 * synthetic access flag.
 */
static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;

问题是,它是如何泄漏给您的…

它通过使用IntelliJs插件读取基于ASM而非javap的字节码泄漏的。应该依赖于官方工具。谢谢不是常量池不能引用类型,而是
ldc
指令不能将
Class
对象这样的引用加载到操作数堆栈。但是类常量池类型已经存在,允许指定
this
super
类型,实现接口并声明引用成员的类。