Lombok 扩展方法:Prevalence/priority?

Lombok extension methods: Prevalence/priority?

首先:我非常喜欢龙目岛计划。很棒的工具!这个 'compile time' 库有很多优秀的方面。

喜欢@ExtensionMethods,我已经点击'feature'几次了,所以现在是时候问这个问题了:

假设我有以下 classes:

@UtilityClass
public class AObject {
    static public String message(final Object pObject) {
        return "AObject = " + (pObject != null);
    }
}
@UtilityClass
public class AString {
    static public String message(final String pObject) {
        return "AString = " + (pObject != null);
    }
}
@ExtensionMethod({ AObject.class, AString.class })
public class Run_Object_String {
    public static void main(final String[] args) {
        System.out.println("\nRun_Object_String.main()");
        final String s = "Bier!";
        final Object o = new Object();

        System.out.println("Testing s: " + s.message());
        System.out.println("Testing o: " + o.message());
        System.out.println("Testing s: " + s.message());
    }
}
@ExtensionMethod({ AString.class, AObject.class })
public class Run_String_Object {
    public static void main(final String[] args) {
        System.out.println("\nRun_String_Object.main()");
        final String s = "Bier!";
        final Object o = new Object();

        System.out.println("Testing s: " + s.message());
        System.out.println("Testing o: " + o.message());
        System.out.println("Testing s: " + s.message());
    }
}
public class ClassPrevalenceTest {
    public static void main(final String[] args) {
        Run_Object_String.main(args);
        Run_String_Object.main(args);
    }
}

输出:

Run_Object_String.main()
Testing s: AObject = true
Testing o: AObject = true
Testing s: AObject = true

Run_String_Object.main()
Testing s: AString = true
Testing o: AObject = true
Testing s: AString = true

这是我盲目假设的:

那么,除了注意添加 @UtilityClass 引用的顺序外,还有其他解决方案吗?

这是我不知道的 Lombok 的一个有趣用法。我认为您可以深入寻找答案的最佳位置是源代码本身,因为关于这项实验性工作的文档看起来很轻松,可以理解。

查看 git 此处:HandleExtensionMethod

我根据以下逻辑猜测,有效“适合”注释中正确方法的区域如下所示。

它似乎没有尝试“最佳”匹配,而是以“第一次”匹配为目标。

也就是说,它似乎迭代了 List<Extension> extensions。由于它是一个 Java 列表,我们假设顺序保留在原始注释中指定扩展名的顺序。

它似乎只是按照列表的顺序工作,return只要某些东西匹配正确的方法和类型形状。

Types types = Types.instance(annotationNode.getContext());
        for (Extension extension : extensions) {
            TypeSymbol extensionProvider = extension.extensionProvider;
            if (surroundingTypeSymbol == extensionProvider) continue;
            for (MethodSymbol extensionMethod : extension.extensionMethods) {
                if (!methodName.equals(extensionMethod.name.toString())) continue;
                Type extensionMethodType = extensionMethod.type;
                if (!MethodType.class.isInstance(extensionMethodType) && !ForAll.class.isInstance(extensionMethodType)) continue;
                Type firstArgType = types.erasure(extensionMethodType.asMethodType().argtypes.get(0));
                if (!types.isAssignable(receiverType, firstArgType)) continue;
                methodCall.args = methodCall.args.prepend(receiver);
                methodCall.meth = chainDotsString(annotationNode, extensionProvider.toString() + "." + methodName);
                recursiveSetGeneratedBy(methodCall.meth, methodCallNode);
                return;
            }
        }

您可以查看其余代码以获得其他见解,因为那里似乎没有太多内容(即行数)可供查看,但不可否认,这是一项令人印象深刻的壮举space.