簡體   English   中英

Lombok 擴展方法:流行/優先級?

[英]Lombok extension methods: Prevalence/priority?

首先:我非常喜歡龍目島項目。 很棒的工具。 這個“編譯時”庫有很多優秀的方面。

喜歡@ExtensionMethod ,我已經多次使用這個“功能”,所以現在是我問這個問題的時候了:

假設我有以下課程:

@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);
    }
}

使用 output:

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
  • 為什么是這樣?
  • 為什么在第一個示例中沒有調用message(String) ,即使它具有比message(Object)更好的方法簽名擬合?
  • 為什么@ExtensionMethod依賴於 arguments 的序列?

這是我盲目的假設:

  • 解析 ExtensionMethods 時,Lombok 會從左到右處理注解值
    • 對於Run_Object_String這意味着:首先AObject ,然后是AString
    • 對於Run_String_Object這意味着:首先是AString ,然后AObject
  • Object-String:將AObject修補到 class Run_Object_String時,將添加message(Object)方法。 並且在使用message(String)方法修補AString時,不會添加它。 大概是因為message(Object)也匹配了對message(String)的調用,所以message(String)不會被添加。
  • String-Object:將AString修補到 class Run_String_Object時,將添加message(String)方法。 當用message(Object)修補AObject class 時,舊的和現在的message(String)方法將不接受調用message(Object) ,因此將添加方法message(Object)

那么,除了非常注意我添加@UtilityClass引用的順序之外,還有其他解決方案嗎?

  • 在添加擴展方法時,Lombok 預處理器是否可以擴展並變得更明智?
  • 你們對此有什么建議,或者對實際發生的事情有什么解釋(與我的假設相反)

這是我不知道的 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;
            }
        }

您可以查看代碼的 rest 以獲得其他見解,因為那里似乎沒有太多(即行數)可供查看,盡管不可否認,在該領域中這是一項令人印象深刻的壯舉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM