static <T extends Number> void gMethod (ArrayList <T> list) {}
ArrayList <Integer> intList = new ArrayList();
gMethod(intList); // allowed
为了进一步说明受限制于Number的泛型将接受Number或它的任何子类的类型参数:
class Thing <T extends Number> {}
Thing <Number> numThing = new Thing();
Thing <Integer> intThing = new Thing();
Thing <Double> dubThing = new Thing(); // All three instances work
鉴于此,我看到使用上限有界通配符与有界泛型相比的唯一好处是,可以声明上限有界通配符类型参数,而不依赖于类或方法已经声明的类型参数。还有更重要的好处我错过了吗?
“…我能看到的使用上限有界通配符与有界泛型通配符的唯一好处…”
如果您的用例只要求您一次使用一个东西
,那么您所描述的简单使用场景就是您所需要的。
但最终会有一个用例,在这个用例中,您需要处理不同种类的东西
。这时,您需要从工具箱中提取稍微高级一些的多态性。
“……我错过了一个更重要的好处吗?……”
一个超级重要的好处,听起来好像你错过了,是类型之间的替代关系;叫做协方差。
例如,既然这样做是合法的:
Integer[] intAry = {2,4,6,8};
Number[] numAry = intAry;
那么直觉上,似乎你应该能够做到这一点:
List<Integer> intList = List.of(8,6,7,5,3,0,9);
List<Number> numList = intList; // but this fails to compile
带有上限的通配符有效地使集合变得协变:
List <? extends Number> numList = intList;
由于Integer
扩展Number
:
Thing<Number> numThing = new Thing<>();
Thing<Integer> intThing = new Thing<>();
numThing = intThing; // but this fails to compile
Thing<? extends Number> numThing = new Thing<>();
numThing = intThing; /* That makes sense! */
同样处理方法。在此声明中:
public static void use(Thing<Number> oneThing){
/*...*/
}
这将无法编译:
Thing<Integer> intThing = new Thing<>();
use(intThing); /* error: no suitable method found for use(Thing<Integer>) */
带有上限的通配符可以使用东西
,就像您直觉上认为的那样:
public static void use(Thing<? extends Number> anyThing){
/* ...*/
}
...
Thing<Integer> intThing = new Thing<>();
use(intThing); /* Perfectly fine! */
null 为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。 多谢了。
上限通配符下限通配符 有人能帮我理解一下吗?
我有下面的地图 有时有一个列表,有时有一个集合作为值。现在我想获取值,但有一个问题,它无法编译。 我知道我可以这样做: 但我有兴趣了解它应该如何与通用getOrDefault方法一起工作
现在我正在尝试构建一个(灵活的)列表,并向其中添加不同类型的对象。 我可以将的实例添加到。但是,当我试图将或的实例添加到同一个列表中时,会出现编译错误。是否足够灵活,可以使用或其超级类的任何实例?和在层次结构树中位于较高位置。为什么我不能将这些实例添加到列表中?
null 编译,我真的不明白为什么。基本上与第1行相同的问题。是的超类,如何将超类的成员放入此中? 编译。与第1行相同的问题。
问号(?)代表通配符,代表泛型中的未知类型。 有时您可能希望限制允许传递给类型参数的类型。 例如,对数字进行操作的方法可能只想接受Number或其子类的实例。 要声明一个上限的Wildcard参数,请列出?,后跟extends关键字,后跟其上限。 例子 (Example) 以下示例说明了如何使用extends来指定上限通配符。 package com.wenjiangs; import java.