了解在java泛型中使用通配符?

Cra*_*han 0 java generics wildcard

我问了一个类似的问题,这是一个更具体的版本,希望得到一个明确的答案.在尝试理解Java通用类型和通配符"?"的用法时,我尝试了以下方法:

List<Integer> li4 = new ArrayList<Integer>();
  li4.add(new Integer(5));
  Integer myInt4 = li4.get(0);
Run Code Online (Sandbox Code Playgroud)

现在我用更通用的类型替换'

List<? extends Integer> li = new ArrayList<Integer>(); 
Integer myInt = li.get(0);
Run Code Online (Sandbox Code Playgroud)

上面的编译很好.似乎上面的'li'被视为一个列表,其中每个元素都是一个Integer(查看li.get(0)调用).我也可以做以下事情:

li = li4;
Run Code Online (Sandbox Code Playgroud)

以上编译并运行良好.但是当我尝试:

li.add(new Integer(5));
Run Code Online (Sandbox Code Playgroud)

我得到以下编译错误(使用Oracle JDeveloper作为IDE):

 Error(24,9):  cannot find method add(java.lang.Integer)
Run Code Online (Sandbox Code Playgroud)

"?extends Integer'应该允许任何扩展Integer的类型.它的行为类似于'get'方法,它返回一个Integer.类似地,当ArrayList被分配给它时它不会抱怨.所以例如'li = new ArrayList<String>()'不编译.那么为什么我可以分配另一个ArrayList<Integer>(),获得一个Integer但不添加整数?

Lou*_*man 5

? extends Integer不会意味着"应该允许扩展整数类型的任何".这意味着这是List<T>针对某些特定的 T扩展Integer的.

所以你从List<? extends Integer>遗嘱中得到的任何东西都会延伸Integer,但你不能只是放入任何东西 - 我们不知道你所投入的类型是否匹配T.

举一个具体的例子,Integer扩展Number.所以你可以写

List<? extends Number> list1 = new ArrayList<Integer>();
List<? extends Number> list2 = new ArrayList<Double>();
Run Code Online (Sandbox Code Playgroud)

但你不应该被允许写list2.add(new MyNumber()),或者list2.add(new Integer(3)),因为list2实际上是一个List<Double>.