为什么我的 Groovy AST 转换会在我的方法末尾插入 null?

Why does my Groovy AST transform insert null at the end of my method?

我编写了一个 AST 转换,它为 JPA 映射 属性 创建了一个 setter(它既设置了本地字段又在关系的另一端调用了 setOwner) :

private static void createSetter(FieldNode field) {
    Parameter parameter = GeneralUtils.param(field.getType(), field.getName());

    BlockStatement body = new BlockStatement();
    body.addStatement(assignS(fieldX(field), varX(parameter)));

    MethodCallExpression setterCall = callX(varX(parameter), "setOwner", varX("this", field.getDeclaringClass()));
    setterCall.setType(ClassHelper.VOID_TYPE);
    body.addStatement(stmt(setterCall));

    MethodNode method = new MethodNode(setterName(field.getName()), ACC_PUBLIC, ClassHelper.VOID_TYPE, new Parameter[] {parameter}, ClassNode.EMPTY_ARRAY, body);
    field.getDeclaringClass().addMethod(method);
}

这行得通,但是生成的方法最后有一个奇怪的 null 语句,被 JD-GUI 反汇编(除了一个奇怪的局部变量):

public void setMore(Simple_MoreStuff more) {
    Simple_MoreStuff localSimple_MoreStuff = more;
    this.more = localSimple_MoreStuff;
    more.setOwner(this);
    null;
}

它似乎不影响实际的正确性,但它很奇怪,而且似乎是一个错误。在MethodCallExpression中,我找到了这个评论,但不知道它是否相关,因为我的方法实际上是无效的(我在上面明确设置了它,它没有任何区别):

//TODO: set correct type here
// if setting type and a methodcall is the last expression in a method,
// then the method will return null if the method itself is not void too!
// (in bytecode after call: aconst_null, areturn)

有没有办法防止生成的方法出现虚假的 null

我没有看过 JD-GUI,所以我不知道这个工具在理解字节码方面的能力如何,这不是来自 Java。但总的来说,反汇编程序只能在某种程度上显示 Java 代码在这种情况下的样子,绝不应该显示来自非 Java 语言的正确代码。所以如果你反汇编 Groovy.

最好不要指望正确的 Java 代码

在这种情况下,我怀疑 JD-GUI 遇到了我们尚未摆脱的解决方法。在某些情况下,我们会在方法结束处添加死代码 const_null,这就是您注意到的。我们这样做是因为如果在方法末尾使用字节码标签,验证器就会出现问题。由于死代码不会影响正确性,我们目前正在使用此解决方案。