关于下列守则:
public class Test <T extends Comparable>{
public static void main(String[] args){
List<String> lst = Array.asList("abc","def");
System.out.println(func(lst));
}
public static boolean func(List<**here**> lst){
return lst.get(0).compareTo(lst.get(1)) == 0;
}
}为什么编写“?扩展可比较的”此处将编译,而编写“可比”将不会编译?
提前谢谢。
发布于 2018-09-07 15:08:14
这是因为泛型是不变的。即使String是Comparable,意思是:
String s = "";
Comparable c = s; // would work这些产品的泛型不起作用:
List<Comparable> listC = List.of();
List<String> listS = List.of();
listC = listS; // will fail不管Comparable和String之间的关系是什么,这都是行不通的。
将该方法的定义更改为:
public static boolean func(List<? extends Comparable> lst) {
...
}这是说:通配符与扩展绑定使类型协变。
这意味着:
List<? extends Comparable> listC = List.of();
List<String> listS = List.of();
listC = listS; // would work here或者简单地说,它意味着List<String>是List<? extends Comparable>的一个子类型。
现在要付出的代价很小,因为listC现在是元素的生产者,这意味着您可以从元素中提取元素,但您不能将任何东西放入其中。
在您理解了这一点之后,您还没有完成,因为该方法的定义将是完全正确的,当这样编写时:
public static <T extends Comparable<? super T>> boolean func(List<T> lst) {
.....
}发布于 2018-09-07 15:05:30
这是因为不能将List<SubClass>转换为List<BaseClass>。让我们假设它可以
List<String> sList = new ArrayList<>();
List<Comparable> cList = (List<Comparable>) sList;
cList.add(5);这将是一个问题,因为整数5不是String,不应该放在List<String>中。
通过使用? extends Comparable,您可以说该函数可以获取与基类具有可比性的任何内容的列表(例如,List<Comparable>、List<String>、List<Integer>等)。
要更正确地定义函数,您应该执行以下操作:
public static <T extends Comparable<T>> boolean func(List<T> lst) {}这使得类型与其自身具有可比性。您的函数比较列表中的第一个和第二个元素,所以最好确保列表中的每个元素实际上都可以与其他元素进行比较。
发布于 2018-09-07 14:48:20
因为
List<String> lst = Array.asList("abc","def");lst列表有泛型类型String,而不是Comparable。String类,hovewer,实现Comparable<String>接口,因此它适合于? extends Comparable泛型类型。
https://stackoverflow.com/questions/52224806
复制相似问题