List<? extends Base> list
List<Base> list
Run Code Online (Sandbox Code Playgroud)
两个声明之间有什么区别吗?
谢谢,
Oli*_*rth 13
是.
List<Base>可以包含所有来自的不同事物的混合物Base. List<? extend Base>包含同类物品(在某种意义上说,它们必须都来自某些特定的,未知的类型,而这些类型又来自Base).
换句话说,List<? extends Base>是基类List<T extends Base>.所以你可以传递List<T extends Base>给任何需要的方法List<? extends Base>.对于采用a的方法,情况也是如此List<Base>.
List<Base> list可以包含类型Base或其任何子类型的元素.JDK类的一些示例:
List<Object> objects = new ArrayList<Object>();
objects.add(new Object()); // adding an Object instance
objects.add("I am a String"); // a String instance is also an Object
objects.add(Integer.valueOf(5)); // an Integer instance is also an Object
Run Code Online (Sandbox Code Playgroud)
但是当您检索元素时,您只能将它们分配给Object类的变量,因为它Object是声明列表的类型参数.
Object first = objects.get(1);
Object second = objects.get(2);
Object third = objects.get(3);
Run Code Online (Sandbox Code Playgroud)
他们真正运行时类仍然是Object,String而且Integer,这样你就可以将它们转换成这些类型,并与他们这样的工作,但这种强制转换可以在运行时失败了ClassCastException,如果不这样做的权利,它通常是不与这些名单的工作是个好主意时尚.
List<? extends Base> list是一个实际上没有被指定用于声明变量的声明,因为正如Daniel Pryden的评论中已经提到的那样 - 你不能add()在其中有任何对象,只有nulls.
List<? extends String> list = new ArrayList<? extends String>();
list.add("a String")); // compile error!
Run Code Online (Sandbox Code Playgroud)
但是您可以将这种有界通配符表达式用于泛型方法参数.List本身的一个例子是addAll()签名是这样的方法:
boolean addAll(Collection<? extends E> c);
Run Code Online (Sandbox Code Playgroud)
这使您可以执行以下操作:
List<String> strings = Arrays.asList("a", "b");
List<Object> objects = new ArrayList<Object>();
objects.addAll(strings);
Run Code Online (Sandbox Code Playgroud)
如果没有<? extend E>通配符它不会是可能的加StringS插入List的ObjectS,因为泛型类型(不同于阵列)不是协变.这意味着a List<String> 不是 a的子类型List<Object>.但是任何String都是Object,对吧?因此,有必要使用有界通配符声明方法参数 - a List<String> 是子类型List<? extends Object>.
同样,我必须指出 - 有界通配符主要指定用于泛型方法参数,而不是方法返回类型或变量声明.
| 归档时间: |
|
| 查看次数: |
3430 次 |
| 最近记录: |