[英]Using java generic types with wild card “?”
While trying to understand java generic types and usage of wild card "?", I tried the following: 在尝试了解Java通用类型和通配符“?”的用法时,我尝试了以下操作:
List<?> li = new ArrayList<Integer>();
List<Integer> li2 = new ArrayList<Integer>();
li2.add(new Integer(6));
li = li2;
The above compiles and runs fine. 上面的代码可以正常运行。 But if I try:
但是,如果我尝试:
li.add(new Integer(5));
I get following compilation error (using Oracle JDeveloper as IDE): 我收到以下编译错误(使用Oracle JDeveloper作为IDE):
Error(24,9): cannot find method add(java.lang.Integer)
Why does the above not compile but the assignment li=li2
is fine? 为什么上面的代码不能编译,但是赋值
li=li2
很好? Also if I want to call li.add(...)
what is an acceptable parameter value? 另外,如果我想调用
li.add(...)
什么是可接受的参数值?
?
is a wildcard type, encompassing all reference types. 是通配符类型,包含所有引用类型。 Values that are going to be assigned to the type
?
将要分配给类型的值
?
must be assignable to any reference type. 必须可分配给任何引用类型。
Integer
is not assignable to all reference types (for example, String s = new Integer(1);
fails). Integer
不能分配给所有引用类型(例如, String s = new Integer(1);
失败)。 In fact, in Java the only value assignable to all reference types is null
, which is the only value you can add to List<?>
实际上,在Java中,可分配给所有引用类型的唯一值是
null
,这是可以添加到List<?>
的唯一值List<?>
Other fun combinations: 其他有趣的组合:
? super Number
? super Number
is a range including types Object
and Number
. ? super Number
是一个范围,包括Object
和Number
类型。 When you write such a value, it has to be both Object
and Number
, ie. 当您编写这样的值时,它必须同时是
Object
和Number
。 Integer
would be okay. Integer
就可以了。 When reading such a value, it will be either Object
or Number
(so, Object
). 当读取这样的值时,它将是
Object
或Number
(即Object
)。
? extends Number
? extends Number
is a range including types Number
and all its subtypes. ? extends Number
是一个范围,包括Number
类型及其所有子类型。 When you write such a value, it has to be of a type of all subtypes of Number, ie. 当您编写这样的值时,它必须是Number的所有子类型的类型,即。 it has to be
null
. 它必须为
null
。 When reading such a value, it will be a Number
. 当读取这样的值时,它将是一个
Number
。
A call to "li" will not bother whether you assigned it an ArrayList<Integer>
or a LikedList<String>
, it will work only on the declared type, that is List<?>
. 调用“ li”将不会影响您是否为其分配了
ArrayList<Integer>
或LikedList<String>
,它仅适用于声明的类型,即List<?>
。
When you declare a generic parameter, it can be applied to return types and to method arguments. 声明通用参数时,可以将其应用于返回类型和方法参数。 For example, in a
List<String>
, you will have a String get(int i)
and a void add(String)
methods. 例如,在
List<String>
,您将具有String get(int i)
和void add(String)
方法。
Both are safe, cause with this methods you can only add (and retrieve) String's from the list. 两者都是安全的,因为使用此方法,您只能从列表中添加(和检索)字符串。
On a List<?>
you will have a Object get(int i)
method, because whatever is in the list it can safely be cast to Object, be it Integer or String. 在
List<?>
您将具有Object get(int i)
方法,因为列表中的任何内容都可以安全地强制转换为Object,无论是Integer还是String。
However, offering a void add(Object)
method, is unsafe, cause would permit you to add a String to an Integer list or vice versa (or any other thing). 但是,提供一个
void add(Object)
方法是不安全的,因为它将允许您将String添加到Integer列表中,反之亦然(或其他任何事情)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.