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
类型,实现接口并声明引用成员的类。