以下是Maurice Naftalin和Philip Wadler在unbounded wildcard types
和raw types
之间进行比较的引用。
我们建议优先使用无限制的通配符类型,而不要使用原始类型
因为它们提供了更强大的静态类型保证;许多错误
使用无界通配符时被捕获为错误的错误只会
如果您使用原始类型,则会被标记为警告。
但是本书没有提供代码示例来说明这种情况。我想知道是否有人可以通过提供代码示例来增加解释?
最佳答案
好吧,您可以改编同一章的某些示例,以重现这种情况。
例如,考虑以下通用类:
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
因此,如您所见,无限制通配符比原始类型提供更好的类型检查保证。