使用无限通配符会捕获错误的情况,但只有在使用原始类型时才会被标记为警告
situations where an error will be caught by using unbounded wildcards, but will only be flagged as a warning if you use raw type
下面是 Maurice Naftalin 和 Philip Wadler 对 unbounded wildcard types
与 raw types
的比较引述,来自 Java generics and collection
。
We recommend using unbounded wildcard types in preference to raw types
because they provide stronger static typing guarantees; many mistakes
that are caught as an error when you use unbounded wildcards will only
be flagged as a warning if you use raw types.
但是这本书没有提供代码示例来说明这种情况。我想知道是否有人可以通过提供代码示例来补充解释?
好吧,您可以改编同一章的一些示例来重现这种情况。
例如,考虑以下泛型 class:
class Node<E> {
private E value;
@Override public String toString(){ return value.toString(); }
}
现在,假设您编写了以下错误代码:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node) {
Node other = (Node) o;
other.value = node.value; //Uh oh! Warning
}
System.out.println(node); //Hello
System.out.println(other); //Hello - WTH!
如果你尝试编译它,你只会得到一个警告,但它仍然可以正常编译:
javac -Xlint:unchecked Node.java
Node.java:21: warning: [unchecked] unchecked assignment to variable value as member of raw type Node
other.value = node.value;
^
1 warning
但是,如果您更改代码以使用无限通配符:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node<?>) {
Node<?> other = (Node<?>) o;
other.value = node.value; //Uh oh! Compiler error
}
现在编译时会出现如下错误:
javac -Xlint:unchecked Node.java
Node.java:21: error: incompatible types: String cannot be converted to CAP#1
other.value = node.value;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
1 error
因此,如您所见,无限通配符提供了比原始类型更好的类型检查保证。
下面是 Maurice Naftalin 和 Philip Wadler 对 unbounded wildcard types
与 raw types
的比较引述,来自 Java generics and collection
。
We recommend using unbounded wildcard types in preference to raw types because they provide stronger static typing guarantees; many mistakes that are caught as an error when you use unbounded wildcards will only be flagged as a warning if you use raw types.
但是这本书没有提供代码示例来说明这种情况。我想知道是否有人可以通过提供代码示例来补充解释?
好吧,您可以改编同一章的一些示例来重现这种情况。
例如,考虑以下泛型 class:
class Node<E> {
private E value;
@Override public String toString(){ return value.toString(); }
}
现在,假设您编写了以下错误代码:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node) {
Node other = (Node) o;
other.value = node.value; //Uh oh! Warning
}
System.out.println(node); //Hello
System.out.println(other); //Hello - WTH!
如果你尝试编译它,你只会得到一个警告,但它仍然可以正常编译:
javac -Xlint:unchecked Node.java
Node.java:21: warning: [unchecked] unchecked assignment to variable value as member of raw type Node
other.value = node.value;
^
1 warning
但是,如果您更改代码以使用无限通配符:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node<?>) {
Node<?> other = (Node<?>) o;
other.value = node.value; //Uh oh! Compiler error
}
现在编译时会出现如下错误:
javac -Xlint:unchecked Node.java
Node.java:21: error: incompatible types: String cannot be converted to CAP#1
other.value = node.value;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
1 error
因此,如您所见,无限通配符提供了比原始类型更好的类型检查保证。