![](/img/trans.png)
[英]bound mismatch error in java generic method when using self-referring type
[英]Generic type mismatch while using a Collector returned by the method - Java 17
我正在試驗records
和streams 。
我創建了這些記錄來計算文本中的字母數。
record Letter(int code) {
Letter(int code) {
this.code = Character.toLowerCase(code);
}
}
record LetterCount(long count) implements Comparable<LetterCount> {
@Override
public int compareTo(LetterCount other) {
return Long.compare(this.count, other.count);
}
static Collector<Letter, Object, LetterCount> countingLetters() {
return Collectors.collectingAndThen(
Collectors.<Letter>counting(),
LetterCount::new);
}
}
這是使用它們的片段:
final var countedChars = text.chars()
.mapToObj(Letter::new)
.collect(
groupingBy(Function.identity(),
LetterCount.countingLetters() // compilation error
// collectingAndThen(counting(), LetterCount::new) // this line doesn't produce error
));
如果我注釋掉collectingAndThen()
用作groupingBy()
中的下游收集器,上面顯示的代碼片段不會產生錯誤。
但是,當我嘗試使用LetterCount.countingLetters()
作為下游收集器時,編譯器會丟失。
我收到以下錯誤消息:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Collector cannot be resolved to a type
Type mismatch: cannot convert from Collector<Letter,capture#17-of ?,LetterCount> to Collector<Letter,Object,LetterCount>
The method countingLetters() from the type LetterCount refers to the missing type Collector
The method entrySet() is undefined for the type Object
接口Collector
具有以下聲明:
public interface Collector<T,A,R>
其中第二個泛型類型參數A
表示可變容器的類型,該容器在內部用於累積歸約結果。 這種類型通常被實現隱藏。
您的方法countingLetters()
聲明返回類型如下:
Collector<Letter, Object, LetterCount>
這意味着此方法返回的收集器的可變容器類型應為Object
。
提醒: generics 是不變的,即如果你說Object
你必須只提供Object
(不是它的子類型,不是未知類型?
,只有Object
類型本身)。
由於以下幾個原因,這是不正確的:
JDK 中內置的所有收集器都隱藏了它們的可變容器類型。 您在代碼中使用的收集器條件聲明返回conting
Collector<T,?,Long>
。 在引擎蓋下,它使用summingLong
,它反過來返回Collector<T,?,Long>
盡管它在內部使用long[]
作為container 。 那是因為公開這些實現細節沒有意義。 因此,您聲明的返回類型的通用參數不符合您要返回的收集器的通用參數。 即因為你被賦予了未知類型?
,您不能聲明返回Object
。
即使您不使用內置收集器,而是使用您自己的自定義收集器,公開其容器的實際類型仍然不是一個好主意。 僅僅是因為在未來的某個時候,您可能想要更改它。
Object
class 是不可變的,因此將其用作容器類型(如果您嘗試實現自定義收集器)是徒勞的,因為它無法累積數據。
底線: countingLetters()
方法返回的收集器中的第二個通用參數不正確。
要修復它,您必須將可變容器的類型更改為:
?
它包含所有可能的類型,即預期提供的收集器可能具有任何類型的可變容器(這就是 JDK 中所有收集器的聲明方式);? extends Object
? extends Object
(這基本上是描述未知類型的更詳細的方式)。public static Collector<Letter, ?, LetterCount> countingLetters()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.