Мне интересно, существует ли когда-либо допустимый прецедент для следующего:
class Base {}
class A implements Comparable<Base> {
//...
}
Кажется, это общий шаблон (см. Collections для ряда примеров), чтобы принять коллекцию типа T
, где T extends Comparable<? super T>
.
Но, по сравнению с базовым классом, технически невозможно выполнить контракт compareTo()
, потому что нет способа гарантировать, что другой класс не расширяет базу с помощью противоречивого сравнения. Рассмотрим следующий пример:
class Base {
final int foo;
Base(int foo) {
this.foo = foo;
}
}
class A extends Base implements Comparable<Base> {
A(int foo) {
super(foo);
}
public int compareTo(Base that) {
return Integer.compare(this.foo, that.foo); // sort by foo ascending
}
}
class B extends Base implements Comparable<Base> {
B(int foo) {
super(foo);
}
public int compareTo(Base that) {
return -Integer.compare(this.foo, that.foo); // sort by foo descending
}
}
У нас есть два класса, расширяющие Base
, используя сравнения, которые не следуют общему правилу (если бы существовало общее правило, оно почти наверняка было бы реализовано в Base
). Однако следующий разбитый сорт будет компилироваться:
Collections.sort(Arrays.asList(new A(0), new B(1)));
Не было бы безопаснее принимать только T extends Comparable<T>
? Или есть какой-то прецедент, который бы подтвердил подстановочный знак?