[英]Inheriting Comparable with generics
試圖設計一個超類,確保所有子類本身都是Comparable
。
/**
* A base class implementing Comparable with itself by delegation.
* @param <T> - The type being wrapped.
*/
static class Distinct<T extends Comparable<T>> implements Comparable<Distinct<T>> {
final T it;
public Distinct(T it) {
this.it = it;
}
@Override
public int compareTo(Distinct<T> o) {
return it.compareTo(o.it);
}
}
/**
* A set of distinct items.
*
* @param <T>
*/
static class ThingHolder<T extends Comparable<T>> {
final Set<T> things;
public ThingHolder() {
this.things = new TreeSet<>();
}
}
/**
* A sample real thing.
*/
static class Thing extends Distinct<String> {
public Thing(String it) {
super(it);
}
}
// This doesn't work - Why?
final ThingHolder<Thing> yz = new ThingHolder<>();
我得到的錯誤是:
com/oldcurmudgeon/test/Test.java:[70,22] error: type argument Thing is not within bounds of type-variable T
where T is a type-variable:
T extends Comparable<T> declared in class ThingHolder
為什么這不起作用? 可以嗎?
X
傳遞給ThingHolder
它必須是Comparable<X>
的子類型(通過ThingHolder
的類聲明)。 Thing
類型傳遞給ThingHolder
它必須是Comparable<Thing>
的子類型。 (根據之前的陳述,將Thing
替換為X
) Thing
擴展了Distinct<String>
,因此實現了Comparable<Distinct<String>>
(通過Thing
的類聲明)。 Thing
與Distinct<String>
類型Distinct<String>
- 盡管它是一個子類型 - 因此類型匹配失敗。 你可以通過調整ThingHolder
的類聲明來解決這個ThingHolder
,如下所示:
class ThingHolder<T extends Comparable<? super T>> {
...
}
一些研究和抨擊提出了這個建議 。
通常,如果您的API只使用類型參數T作為參數,則其使用應該利用較低的有界通配符(?super T)。
一些修補(添加? super T
)略微放松限制葉:
/**
* A set of distinct items.
*
* Don't like the <?> in there but a <T> is not accepted.
*
* @param <T>
*/
static class ThingHolder<T extends Comparable<? super T>> {
final Set<T> things = new TreeSet<>();
}
final ThingHolder<Thing> holder = new ThingHolder<>();
這對編譯器來說是可以接受的。
一般我不喜歡用?
為了填補空白,因為它通常允許過多,但在這種情況下,我會留下它。
只需將ThingHolder
類簽名更改為:
static class ThingHolder<T extends Comparable> {
...
}
即從Comparable
刪除<T>
,沒有必要。
class ThingHolder<T extends Comparable<T>>
聲明事物 T
必須與自身相當,但class Thing extends Distinct<String>
不是。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.