以下是Maurice Naftalin和Philip Wadler在unbounded wildcard typesraw 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


因此,如您所见,无限制通配符比原始类型提供更好的类型检查保证。

10-01 05:19
查看更多