[英]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 的序列?這是我盲目的假設:
Run_Object_String
這意味着:首先AObject
,然后是AString
Run_String_Object
這意味着:首先是AString
,然后AObject
AObject
修補到 class Run_Object_String
時,將添加message(Object)
方法。 並且在使用message(String)
方法修補AString
時,不會添加它。 大概是因為message(Object)
也匹配了對message(String)
的調用,所以message(String)
不會被添加。AString
修補到 class Run_String_Object
時,將添加message(String)
方法。 當用message(Object)
修補AObject
class 時,舊的和現在的message(String)
方法將不接受調用message(Object)
,因此將添加方法message(Object)
。 那么,除了非常注意我添加@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;
}
}
您可以查看代碼的 rest 以獲得其他見解,因為那里似乎沒有太多(即行數)可供查看,盡管不可否認,在該領域中這是一項令人印象深刻的壯舉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.