我正在用ASM测试ACC_SYNTHETIC的方法。以下是我的代码
public static void generateMethodBean() throws IOException {
System.out.println("11111");
ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "cn/curious/asm/Bean", null, "java/lang/Object", null);
MethodVisitor m0Visitor = cw.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, "lambda$main$1", "()V", null, null);
m0Visitor.visitCode();
m0Visitor.visitInsn(Opcodes.RETURN);
m0Visitor.visitMaxs(0, 0);
m0Visitor.visitEnd();
cw.visitEnd();
byte[] buffer = cw.toByteArray();
// StringWriter stringWriter = new StringWriter();
// PrintWriter printWriter = new PrintWriter(stringWriter);
// CheckClassAdapter.verify(new ClassReader(buffer), true, printWriter);
// System.out.println(printWriter.toString());
File file = new File(FILE_PATH_PREFIX + File.separator + "Bean2.class");
FileUtils.writeByteArrayToFile(file, buffer);
}但是结果类文件没有任何内容。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package cn.curious.asm;
public class Bean {
}我对ACC_SYNTHETIC感到困惑,如何正确使用它?
更新
这是javap输出。-p让它正常工作。
javap -v -l -s -p Bean.class
Classfile /Users/Documents/work/idea_workspace/asmtest/src/main/java/cn/curious/asm/Bean.class
Last modified 2020-3-5; size 127 bytes
MD5 checksum 7367bcf65d9a32a72e4261101d3697cc
public class cn.curious.asm.Bean
minor version: 0
major version: 52
flags: ACC_PUBLIC
Constant pool:
#1 = Utf8 cn/curious/asm/Bean
#2 = Class #1 // cn/curious/asm/Bean
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 lambda$main$1
#6 = Utf8 ()V
#7 = Utf8 Code
{
private static void lambda$main$1();
descriptor: ()V
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=0, args_size=0
0: return
}发布于 2020-03-05 11:50:02
这就是合成方法背后的想法,这些方法是由编译器生成的,所以反编译程序通常在默认情况下跳过它,因为根据定义,它们不应该在源代码中使用。
就像java规范一样,声明
jvm之一:
-- ACC_SYNTHETIC标志指示此方法是由编译器生成的,除某些例外情况外,它不会出现在源代码中。
尝试使用javap -verbose -private -s -classpath yourJar.jar my.Class (或者直接使用类字段),它应该列出所有的方法。或者生成第二个普通方法,它将调用这个合成方法并检查您是否可以运行它。或者使用反射和getDeclaredMethods方法得到所有声明的方法,包括合成的方法。
https://stackoverflow.com/questions/60544549
复制相似问题