java 中通用类型的子类型
Subtype of generic type in java
我对 java 中泛型的子类型感到困惑。我在下面有一个示例。
public class Class2{
public static <T extends Number> void set(List<T> list){
List<T> numberList = list;;
}
public static <T extends Integer> List<T> get(){
List<T> list = new ArrayList<T>();
return list;
}
}
//Does this line is the same as the two below line?
Class2.set(Class2.get());
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numberList = intList;
我的问题:
有什么不同
Class2.set(Class2.get());
和
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numberList = intList;
更新#1:
变化
public static <T> void set(List<T> list)
至
public static <T extends Number> void set(List<T> list)
更新#2:
看图(取自docs.oracle about generic in java)
Link:https://docs.oracle.com/javase/tutorial/figures/java/generics-wildcardSubtyping.gif
从图中我们知道List<? extends Integer>
是List<? extends Number>
的子类型。而我们可以为List<? extends Number>
.
的变量赋值List<? extends Integer>
的变量
在我上面的例子中,我真的为List<T extends Number>
的变量分配了List<T extends Integer>
的变量吗?如果是这样,List<T extends Number>
是 List<T extends Integer>
的子类型吗?你能告诉我如何证明它是否存在吗?
P/S: Link post Oracle 文档:https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
class2
中设置的方法采用一个列表,其中所有元素都是 T
类型并且 T
是 Number
或 class 的任何子 class =20=]:
public static <T extends Number> void set(List<T> list){
List<T> numberList = list;
}
这会将输入参数list
赋值给numberList
,两者只能包含一种类型的元素,由T
表示(T
需要是Number
或 Number
的子类型,例如 Integer
).
另一方面,方法get
将return一个元素列表,其中每个元素都是T
类型,<T extends Integer>
意味着T
必须是 Integer
或 Integer
的子 class 之一。我们需要明白这个 T
和上面方法 set
中定义的不一样。
现在是下面一行:
Class2.set(Class2.get());
实际上用每个元素都属于同一类型 T
的元素初始化 numberList
。另一方面,我们有:
List<? extends Integer> intList = new ArrayList<>();
混淆似乎缩小了:List <? extends Integer>
和 List <T extends Number>
。所以 IMO 的区别是:
List <? extends Integer>
表示它是 "unknown type" 的列表,它将扩展 Integer
并且根据规则 PECS(Producer Extends Consumer Super ) 这可以生产元素但不能消耗元素。
List<T extends Integer>
是一个类型为 super class Integer
的列表,我们可以读取或添加元素到列表中。
附带一提,签名应该是 List <? extends Number>
而不是 List <? extends Integer>
,因为 Integer
是 final
并且不能被子 classed。
使用extends
List<? extends Number> list1 = new ArrayList<Number>(); // Number "extends" Number (in context)
List<? extends Number> list2 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> list3 = new ArrayList<Double>(); // Double extends Number
使用super
List<? super Integer> list4 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer
List<? super Integer> list5 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> list6 = new ArrayList<Object>(); // Object is a superclass of Integer
编辑:
方法 get
return 是类型为 T
的元素列表(T 可以是 Integer
或子类型):
List<Integer> list1 = Class2.get();
现在,对于 set
方法,以下所有方法都有效:
List<Integer> list1 = Class2.get();
Class2.set(list1);
List<Number> list2 = new ArrayList<Number>();
Class2.set(list2);
List<Integer> list3 = new ArrayList<Integer>();
Class2.set(list3);
如doc
所述
Integer
is a subtype of Number
but List<Integer>
is not subtype
of List<number>
, rather these are not related at all. The common
parent of List<Number>
and List<Integer>
is List<?>
.
正如我上面所解释的,List<? extends Integer>
将接受 Integer
而 List<?extends Number>
则更加轻松。所有这些之间的关系由image表示。
我对 java 中泛型的子类型感到困惑。我在下面有一个示例。
public class Class2{
public static <T extends Number> void set(List<T> list){
List<T> numberList = list;;
}
public static <T extends Integer> List<T> get(){
List<T> list = new ArrayList<T>();
return list;
}
}
//Does this line is the same as the two below line?
Class2.set(Class2.get());
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numberList = intList;
我的问题:
有什么不同Class2.set(Class2.get());
和
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numberList = intList;
更新#1: 变化
public static <T> void set(List<T> list)
至
public static <T extends Number> void set(List<T> list)
更新#2: 看图(取自docs.oracle about generic in java) Link:https://docs.oracle.com/javase/tutorial/figures/java/generics-wildcardSubtyping.gif
从图中我们知道List<? extends Integer>
是List<? extends Number>
的子类型。而我们可以为List<? extends Number>
.
List<? extends Integer>
的变量
在我上面的例子中,我真的为List<T extends Number>
的变量分配了List<T extends Integer>
的变量吗?如果是这样,List<T extends Number>
是 List<T extends Integer>
的子类型吗?你能告诉我如何证明它是否存在吗?
P/S: Link post Oracle 文档:https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
class2
中设置的方法采用一个列表,其中所有元素都是 T
类型并且 T
是 Number
或 class 的任何子 class =20=]:
public static <T extends Number> void set(List<T> list){
List<T> numberList = list;
}
这会将输入参数list
赋值给numberList
,两者只能包含一种类型的元素,由T
表示(T
需要是Number
或 Number
的子类型,例如 Integer
).
另一方面,方法get
将return一个元素列表,其中每个元素都是T
类型,<T extends Integer>
意味着T
必须是 Integer
或 Integer
的子 class 之一。我们需要明白这个 T
和上面方法 set
中定义的不一样。
现在是下面一行:
Class2.set(Class2.get());
实际上用每个元素都属于同一类型 T
的元素初始化 numberList
。另一方面,我们有:
List<? extends Integer> intList = new ArrayList<>();
混淆似乎缩小了:List <? extends Integer>
和 List <T extends Number>
。所以 IMO 的区别是:
List <? extends Integer>
表示它是 "unknown type" 的列表,它将扩展Integer
并且根据规则 PECS(Producer Extends Consumer Super ) 这可以生产元素但不能消耗元素。List<T extends Integer>
是一个类型为 super classInteger
的列表,我们可以读取或添加元素到列表中。附带一提,签名应该是
List <? extends Number>
而不是List <? extends Integer>
,因为Integer
是final
并且不能被子 classed。
使用extends
List<? extends Number> list1 = new ArrayList<Number>(); // Number "extends" Number (in context)
List<? extends Number> list2 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> list3 = new ArrayList<Double>(); // Double extends Number
使用super
List<? super Integer> list4 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer
List<? super Integer> list5 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> list6 = new ArrayList<Object>(); // Object is a superclass of Integer
编辑:
方法 get
return 是类型为 T
的元素列表(T 可以是 Integer
或子类型):
List<Integer> list1 = Class2.get();
现在,对于 set
方法,以下所有方法都有效:
List<Integer> list1 = Class2.get();
Class2.set(list1);
List<Number> list2 = new ArrayList<Number>();
Class2.set(list2);
List<Integer> list3 = new ArrayList<Integer>();
Class2.set(list3);
如doc
所述
Integer
is a subtype ofNumber
butList<Integer>
is not subtype ofList<number>
, rather these are not related at all. The common parent ofList<Number>
andList<Integer>
isList<?>
.
正如我上面所解释的,List<? extends Integer>
将接受 Integer
而 List<?extends Number>
则更加轻松。所有这些之间的关系由image表示。