有界通配符和函数参数的关系

时间:2016-04-14 22:10:09

标签: java generics type-safety

假设我们从// Store your new line character var newLine = '&#10'; // Create a phantom <div> elment and set the HTML content for it // then return the text var title = $('<div/>').html('hello' + newLine + 'world').text(); // Finally set the attribute to the text $("#go").attr("title", title); Sub继承了compareTo

Super

采用class Super implements Comparable<Super> { @Override public int compareTo(Super o) { return 0; } } class Sub extends Super {} 列表的通用方法max

Comparable

如果我们尝试使用public static <T extends Comparable<T>> T max(List<T> list) { return null; } 列表调用max,我们会收到编译时错误,因为Sub没有实现{{1} }}。这就是我的预期!

Sub

然后我改变Comparable<Sub>个参数只接受两个T实例并测试它:

max(new ArrayList<Sub>()); // error, Sub should implement Comparable<Sub>

没有编译时错误,非运行时!

类型安全方面的max方法有什么区别?

1 个答案:

答案 0 :(得分:3)

max(T,T)让编译器推断出T可以是Super并对参数进行扩展转换。

另一方面,max(List<T>)不是那么灵活,因为泛型是不变的(在Paul的链接中解释)。编译器无法对List执行转换,因此T必须完全Sub

在这两种情况下,您都应该更改绑定到此的类型变量:

public static <T extends Comparable<? super T>> T max(List<T> list) {...}
//                                  ^^^^^^^^^

它的限制性较小,可以让你这样做:

Sub s0 = max(new ArrayList<Sub>());
Sub s1 = max(new Sub(), new Sub());

第2行也不会使用限制性更强的边界编译,你可能错过了,因为你忽略了示例中的返回值。

? super T也是how Java SE does it。)