首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ASM Opcodes.ACC_SYNTHETIC

如何使用ASM Opcodes.ACC_SYNTHETIC
EN

Stack Overflow用户
提问于 2020-03-05 11:37:33
回答 1查看 405关注 0票数 1

我正在用ASM测试ACC_SYNTHETIC的方法。以下是我的代码

代码语言:javascript
复制
    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);

    }

但是结果类文件没有任何内容。

代码语言:javascript
复制
//
// 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让它正常工作。

代码语言:javascript
复制
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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-05 11:50:02

这就是合成方法背后的想法,这些方法是由编译器生成的,所以反编译程序通常在默认情况下跳过它,因为根据定义,它们不应该在源代码中使用。

就像java规范一样,声明

  1. 编译器发出的构造必须标记为合成结构,如果它与源代码中显式或隐式声明的构造不对应,除非发出的构造是类初始化方法(JVMS§2.9)。

jvm之一:

-- ACC_SYNTHETIC标志指示此方法是由编译器生成的,除某些例外情况外,它不会出现在源代码中。

尝试使用javap -verbose -private -s -classpath yourJar.jar my.Class (或者直接使用类字段),它应该列出所有的方法。或者生成第二个普通方法,它将调用这个合成方法并检查您是否可以运行它。或者使用反射和getDeclaredMethods方法得到所有声明的方法,包括合成的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60544549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档