问题描述
考虑以下代码:
public <T> List<T> meth(List<?> type)
{
System.out.println(type); // 1
return new ArrayList<String>(); // 2
}
它不会在第2行进行编译,表示必须使用List.
It does not compile at line 2, saying that List is required.
现在,如果将其更改为:
Now, if it's changed to:
public <T> List<?> meth(List<T> type)
{
System.out.println(type); // 1
return new ArrayList<String>(); // 2
}
它确实可以编译.为什么?我认为用T声明通用类型和使用通配符之间的区别在于,当使用通配符时,不能将新元素添加到集合中.为什么<?>
允许返回List的子类型?我在这里遗漏了什么,明确的规则是什么以及如何应用它?
It does compile. Why? I thought the difference between declaring a generic type with T and using the wildcard was that, when using the wildcard, one cannot add new elements to a collection. Why would <?>
allow a subtype of List to be returned? I'm missing something here, what's the explicit rule and how it's being applied?
推荐答案
区别在于返回类型声明. List<String>
不是List<T>
的子类型,但是它是List<?>
的子类型.
The difference is in the return type declaration. List<String>
is not a subtype of List<T>
, but it is a subtype of List<?>
.
List<?>
对其类型变量不做任何假设,因此以下语句是有效的:
List<?>
makes no assumptions regarding its type variable, so the following statements are valid:
List<?> l0 = new ArrayList<String>();
List<?> l1 = new ArrayList<Object>();
List<? extends Number> ltemp = null;
List<?> l2 = ltemp;
List<T>
假定将类型参数声明为List<String>
或List<Object>
时,将在客户端的上下文中解析该类型参数(例如,type use).在方法主体中,您也不能对此做任何假设.
List<T>
assumes that the type argument will be resolved in the context of client (e.g. type use), when you declared it as List<String>
or List<Object>
. Within the method body, you cannot make any assumptions about it either.
这篇关于Java通用方法问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!