当我试图解决锻炼时from generics tutorial Q&A我的答案略有不同
我的答案
public static <T extends Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) //Option1
public static <T extends Comparable<T>>
T max(List<? extends T> list, int begin, int end) //Option2
来自下面的引用答案
所以我的问题是
选项1:如果T extends Object & Comparable<? super T>
替换为T extends Comparable<? super T>
,会有什么不同吗?不是extends Object
隐含的吗?
选项2:如果将Comparable<? super T>
替换为Comparable<T>
,会有什么不同吗?如果是这样?
Eclipse代码完成在Ctrl + 1 List<? extends Comparable<? super Comparable<? super T>>> list;
上创建局部变量max(list, 1, 10);
,这有点冗长。如何定义扩展Comparable<? super T>
的类(层次结构),创建列表并将实例添加到列表中并调用下面的方法?基本上我想知道在将类实例max()
添加到A or B
class B extends A
编写通用方法以查找范围中的最大元素 列表的[开始,结束]。
答案:
import java.util.*;
public final class Algorithm {
public static <T extends Object & Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) {
T maxElem = list.get(begin);
for (++begin; begin < end; ++begin)
if (maxElem.compareTo(list.get(begin)) < 0)
maxElem = list.get(begin);
return maxElem;
}
}
答案 0 :(得分:8)
如果
Comparable<? super T>
替换为Comparable<T>
会有什么不同吗?如果是这样的话?
请注意,可比较始终是消费者,即Comparable<T>
消费T
个实例,因此最好使用Comparable<? super T>
代替{{ 1}}(引用 - PECS )。如果您要比较超类实现Comparable<T>
的类型,它会有所不同。请考虑以下代码:
Comparable<SuperType>
现在,如果您将类型参数设为class Parent implements Comparable<Parent> {
protected String name;
@Override
public int compareTo(Parent o) {
return this.name.compareTo(o.name);
}
}
class Child extends Parent {
public Child(String name) {
this.name = name;
}
}
,则无法为T extends Comparable<T>
调用该方法,因为 Child 未实现{{1}但是List<Child>
:
Comparable<Child>
因此,类型参数边界应为Comparable<Parent>
。
请注意,您无法将 Child 类更改为:
public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) {
...
}
public static void main(String[] args) {
List<Child> list = new ArrayList<Child>();
max(list, 0, 2); // Error with current method. Child does not implement Comparable<Child>
}
因为在这种情况下, Child 类将从相同泛型类型的不同实例化扩展,这是不允许的。
如果将
T extends Comparable<? super T>
替换为class Child extends Parent implements Comparable<Child>
,会有什么不同吗?是不是extends Object隐含?
嗯,两个界限之间存在差异。在1 st 界限中,类型参数的擦除为T extends Object & Comparable<? super T>
,而在2 nd 界限中,擦除为T extends Comparable<? super T>
。< / p>
因此,如果没有绑定Object
,您的代码将编译为:
Comparable
当您正在泛化遗留的非通用代码时,可能会出现此问题。将Object
也作为上限以避免破坏字节代码兼容性是必要的。您可以在此链接上阅读更多相关信息:Angelika Langer - Programming Idioms
答案 1 :(得分:0)
看起来有更多的通配符。我可能会选择
public static <T extends Comparable<? super T>>
T max(List<T> list, int begin, int end)
更受限制的版本:
public static <T extends C, C extends Comparable<C>>
T max(List<T> list, int begin, int end)
即。 T
必须具有与本身相当的超类型。例如,T
不能是Foo
class Foo implements Comparable<Object>
无论如何,Foo没有意义; a Comparable只能与其自身类型进行有意义的比较。条款C extends Comparable<C>
承认这一事实。