Java 通用类型:List <? extends Number> 和 List <T extends Number>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18187005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Generic type : difference between List <? extends Number> and List <T extends Number>
提问by Rakesh Soni
Java Generic type : what is the difference between
Java 泛型类型:有什么区别
(1) List <? extends Number>
(2) List <T extends Number>
as per my understanding
按照我的理解
(1) List <? extends Number>
is the
Readonly List of "unknown" data type with super class "Number". we can read the element only but can not add
(1)List <? extends Number>
是具有超类“Number”的“未知”数据类型的只读列表。我们只能读取元素但不能添加
(2) List <T extends Number>
List of data type with super class "Number". we can read and addthe elements into the list
(2)List <T extends Number>
具有超类“Number”的数据类型列表。我们可以读取元素并将其添加到列表中
Please see the below code example
请看下面的代码示例
class TestGen{
public static void main(String[] args) {
double result = 0.0;
List<Integer> intList = new ArrayList<Integer>();
intList.add(10);
intList.add(20);
intList.add(30);
result = TestGen.sumOfList1(intList);
System.out.println("Result=" + result);
result = TestGen.sumOfList2(intList);
System.out.println("Result=" + result);
}
public static double sumOfList1(List<? extends Number> list) {
double s = 0.0;
for (Number n : list)
s += n.doubleValue();
return s;
}
public static <T extends Number> double sumOfList2(List<T> list) {
double s = 0.0;
// getting error while trying to add new element
// list<T> is not applicable for argument(Integer) : Why ?
list.add(new Integer(40));
for (Number n : list)
s += n.doubleValue();
return s;
}
}
When I am trying to add the Integer (or even Number object) into the sumOfList2 then getting the error. Please explain what is wrong here ?
当我尝试将 Integer(甚至 Number 对象)添加到 sumOfList2 中时,出现错误。请解释这里有什么问题?
采纳答案by venkat balabhadra
Basic difference is if you use T extends Number
then you can refer to the type T
:list.add((T) new Integer(40));
基本区别是如果你使用T extends Number
那么你可以参考类型T
:list.add((T) new Integer(40));
Where as if you use ? extends Number
then you can notrefer to the type, but you can still say:((List<Integer>)list).add((int) s);
如果你使用? extends Number
then 你不能引用类型,但你仍然可以说:((List<Integer>)list).add((int) s);
回答by assylias
In sumOfList2
, T
is a specific subclass of Number
, but it can be any of them. For example T
could be BigDecimal
, and you can't add an Integer
to a List<BigDecimal>
.
在sumOfList2
,T
是 的特定子类Number
,但它可以是其中的任何一个。例如T
可能是BigDecimal
,并且您不能将 an 添加Integer
到List<BigDecimal>
。
If you want to be able to add any types of number to the list, it has to be a List<Number>
:
如果您希望能够将任何类型的数字添加到列表中,它必须是List<Number>
:
public static double sumOfList2(List<Number> list) {...}
回答by Eric Jablow
In isolation, there isn't much difference. However, two instances of List<? extends Number>
in a single context are completely unrelated, while two instances of List<T extends Number>
in a single context refer to the same T
and the same interface.
单独来看,差别不大。但是,List<? extends Number>
单个上下文中的两个实例是完全不相关的,而单个上下文中的两个实例List<T extends Number>
指的是同T
一个接口。
public void addAll(List<? extends Number> to, List<? extends Number> from) {
for (Number n: from) {
to.add(n);
}
}
This method fails because n
can't be added to to
, and also failed because the member types of from
and to
can be completely different.
因为此方法将失败n
不能被添加到to
,也失败,因为构件类型from
和to
可以完全不同。
public <T> void addAll(List<T extends Number> to, List<T extends Number> from) {
for (T n: from) {
to.add(n);
}
}
This method compiles fine. It isn't necessary; Collections
has a better version, but it will run without error.
这个方法编译得很好。没有必要;Collections
有一个更好的版本,但它会运行没有错误。
回答by asadnwfp
The first case is very simple and its known from T extends Number
That T is an Object which is of type Number class or its child.
This means if we have a method that uses T as a type of Number we can manipulate our method accordingly i.e
第一种情况非常简单,从T extends Number
That T可知它是一个类型为 Number 类或其子类的对象。这意味着如果我们有一个使用 T 作为 Number 类型的方法,我们可以相应地操作我们的方法,即
<T extends Number> void myMethod ( List <T> num){
num.add(1); // 1 is an Integer
num.add(2.3) // 2.3 is a Double
}
But in this *Wild character '?' * case we don't know what kind of Object is going to be referenced even though if it extends Number, but it can be any kind of Object
但是在这个 *Wild 字符 '?' 中 * 即使扩展了Number,我们也不知道将引用哪种类型的对象,但它可以是任何类型的对象
void myMethod( List <? extends Number> num){
// num.add(1); // not a valid statement, as we dont know if '1' is of the type '?'
// num.add(2.3) // not a valid statement, as we dont know if '2.3' is of the type '?'
}
So the only value that can be written down in such statements is null, as any type of Object can be null.
因此,可以在此类语句中写下的唯一值是null,因为任何类型的 Object 都可以为 null。
void myMethod( List <? extends Number> num){
num.add(null)
}
Such methods are Read Only methods.
此类方法是只读方法。
回答by Samba Namuduri
1)
1)
List <? extends Number>
It would be appropriate to use
使用它是合适的
List<Integer> list = Arrays.asList(0,1,2,3,4);
Which does not throw you an error.
这不会给您带来错误。
List <Double> list = Arrays.asList(0.0,0.1,0.2,0.3,0.4);
then you can add it to
然后你可以将它添加到
result = TestGen.sumOfList1(list);
2) List
2) 列表
List<Integer> list = new ArrayList<Integer>();
list.add(0);
list.add(1); Would do the job.