这两者有什么区别:
static void findMax(LinkedList<? extends Number> list){...}
并且:
static <T extends Number> void findMax(LinkedList<T> list){...}
由于两者都可以使用,我想知道它们之间是否有任何重大区别,并且哪一个更受推荐。
T
,而在第一个版本中无法访问。static <T extends Number> T findMax(LinkedList<T> list){...}
或许你需要创建一个新的T列表:
static <T extends Number> void findMax(LinkedList<T> list){
List<T> copyAsArrayList = new ArrayList<> (list);
//do something with the copy
}
如果您不需要访问T
,两个版本在功能上是等效的。
T
,它们在功能上是不等效的。 - emoryT
*”时,它们才是等价的。特别是当你写list.add(someT);
时,你需要访问T
(对于List<E>
,签名是add(E e)
),在这种情况下使用? extends Number
是行不通的。如果你只需要检查列表的大小(例如),你不需要访问T
,两个版本都是功能上等价的。请重新阅读我的答案。 - assyliasArrayList <? extends Something>
添加值时会得到编译器错误?” - darijan第一种情况适用于您只关心findMax
接受符合某些条件的列表(在您的情况下,是扩展Number
类型的列表)。
static Number findMax(LinkedList<? extends Number> list) {
Number max = list.get(0);
for (Number number : list) {
if (number > max) {
max = number;
}
}
return max;
}
此方法返回Number
。例如,如果您有一个自己扩展了Number
并具有一些特殊方法的类,并且希望稍后在此方法的结果上使用,则可能会出现问题。
第二个应该在您计划在方法体中使用精确类型T
,作为方法参数或方法返回类型时使用。
static <T extends Number> T findMax(LinkedList<T> list, T currentMax) {
T max = currentMax;
for (T number : list) {
if (number > max) {
max = number;
}
}
return max;
}
结论:
从功能上来看,它们几乎是等同的,唯一的区别是,具有未知类型 (?
) 的列表不能被修改。
findMax(LinkedList<? extends T> list)
替换 findMax(LinkedList<T> list)
。 - emorystatic void findMax(LinkedList<? extends Number> list){
list.add(list.get(0)); <-- compile error
}
您只能向列表中添加null,不能添加其他内容。
与此同时,这样编译不会出现任何错误或警告。
static <T extends Number> void findMax2(LinkedList<T> list){
list.add(list.get(0)); <-- no error
}
list.add(list.get(0));
的示例。第一个签名的API能执行这个操作吗?可以。非常简单。只需让第一个调用第二个(将第二个变成内部私有方法)。这被称为“捕获助手”。事实上,您可以通过这样做证明两者可以从外部代码的角度“做”相同的事情(“做”的方式包括调用其他方法等内部手段)。static void findMax(LinkedList<? extends Number> list){
findMaxPrivate(list);
}
static static <T extends Number> void findMaxPrivate(LinkedList<T> list){
list.add(list.get(0));
}
我认为关于在第二个方法体中访问参数T的问题已经有了很好的答案。
我想补充说,如果您有许多需要按类型链接的参数,则需要使用第二种符号。例如:
static <T extends Number> int getPosition(LinkedList<T> list, T element){...}
如果不使用一个通用类型参数<T>
,您将无法强制上述约束条件。
static <T extends Number> T findMax(List<T> list){ return list.get(0)}
。 - Balint Bako