List<? extends Base> list
List<Base> list这两个声明之间有什么区别吗?
谢谢,
发布于 2012-02-29 03:35:16
是。
List<Base>可以包含所有从Base派生的不同内容的混合。List<? extend Base>包含同构项(从某种意义上说,它们都必须派生自某个特定的未知类型,而这些类型又派生自Base)。
换句话说,List<? extends Base>是List<T extends Base>的基类。因此,您可以将List<T extends Base>传递给任何接受List<? extends Base>的方法。对于采用List<Base>的方法,情况并非如此。
发布于 2012-02-29 05:12:41
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但是在检索元素时,只能将它们赋给Object类的变量,因为Object是声明列表的类型参数。
Object first = objects.get(1);
Object second = objects.get(2);
Object third = objects.get(3);它们真正的运行时类仍然是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!但是您可以对泛型方法参数使用这种有界通配符表达式。来自List本身的一个示例是addAll()方法,它的签名是:
boolean addAll(Collection<? extends E> c);这使您能够执行以下操作:
List<String> strings = Arrays.asList("a", "b");
List<Object> objects = new ArrayList<Object>();
objects.addAll(strings);如果没有<? extend E>通配符,就不可能将这些String添加到Objects的List中,因为泛型类型(与数组不同)不是协变的。这意味着List<String> 不是 List<Object>的子类型。但是任何String都是Object,对吧?因此,有必要使用有界通配符声明方法参数-a List<String> is a subtype of List<? extends Object>。
我必须再次指出,有界通配符主要是为泛型方法参数指定的,而不是为方法返回类型或变量声明指定的。
https://stackoverflow.com/questions/9488445
复制相似问题