[英]Generics: Upper Bounded Wildcards conversion/casting error
這是測試:
@Test
public void genericsTest() {
String s = "x";
List<? extends String> strings = singletonList(s);
Optional<Function<String, List<? extends String>>> optionalSelector = Optional.empty();
optionalSelector.map(selector -> selector.apply(s)).orElse(strings);
}
這是錯誤:
java: incompatible types: java.util.List<capture#1 of ? extends java.lang.String> cannot be converted to java.util.List<capture#2 of ? extends java.lang.String>
當然,它可以使用原始類型技巧來修復。
optionalSelector.map(selector -> selector.apply(s)).orElse((List)strings);
但我想了解這個錯誤的原因。
更新 :
它不是帶有通配符的列表的重復導致Generic voodoo錯誤 ,這是關於添加到上限通配符列表; 通配符指南中也很好地描述了這個主題。
在我的情況下,我不會嘗試在列表中添加內容,如上所示。
此外,錯誤消息也不同。
這里的多級類型推斷似乎有問題。 有了這條線:
optionalSelector.map(selector -> selector.apply(s)).orElse(strings);
通過調用map
,您正在嘗試轉換原始的Optional<Function<String, List<? extends String>>>
Optional<Function<String, List<? extends String>>>
為Optional<List<? extends String>>
Optional<List<? extends String>>
。 然后,使用orElse
,您嘗試將其轉換為List<? extends String>
List<? extends String>
。 這看似合理。
通過給中間步驟一個顯式類型,我可以讓它編譯而不需要轉換為原始類型。
Optional<List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
這表明如果編譯器可以推斷出map
的調用結果是一個Optional<List<? extends String>>
Optional<List<? extends String>>
,然后調用orElse
將編譯。
但是,我可以將顯式類型更改為intermedSelector
的聲明編譯的內容,但是對orElse
的調用不會編譯。 我從Optional<List<? extends String>>
更改了interMedSelector
的顯式類型Optional<List<? extends String>>
Optional<List<? extends String>>
為Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
,添加? extends
? extends
。
Optional<? extends List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
這里的錯誤類似於你得到的錯誤:
J.java:26: error: incompatible types: List<CAP#1> cannot be converted to CAP#2
List<? extends String> result = intermedSelector.orElse(strings);
^
where CAP#1,CAP#2 are fresh type-variables:
CAP#1 extends String from capture of ? extends String
CAP#2 extends List<? extends String> from capture of ? extends List<? extends String>
使用您的代碼,編譯器必須推斷出一些意外的,但與Optional<List<? extends String>>
Optional<List<? extends String>>
。 我不知道編譯器的捕獲類型是否是Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
Optional<? extends List<? extends String>>
或其他東西,但這似乎是你得到錯誤的原因。
我的解決方案
Optional<List<? extends String>> intermedSelector = optionalSelector.map(selector -> selector.apply(s));
intermedSelector.orElse(strings);
如果我為map
的調用提供了正確的類型參數,則可以在一個語句中表示,因此編譯器不會推斷出一些意外的事情。
optionalSelector.<List<? extends String>>map(selector -> selector.apply(s)).orElse(strings);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.