-1

如果我们可以使用 Generic 类型解决问题,为什么 Java 提供了 Unbounded 通配符。例如

class UnBoundedUsage {

     //Method 1
     public static void unboundedMethod(List<?> list) {
        for(Object obj : list) {
           System.out.println(obj);
        }
     }

     //Method 2
     public static <T> void methodWithType(List<T> list) {
        for(T obj : list) {
           System.out.println(obj);
        }
     }
}

谁能帮我理解Method 2是否可以解决我们的要求,那么为什么我们需要Method 1。意思是,哪个问题可以使用无界通配符解决,而不能使用通用方法类型(例如方法 2)解决?

4

1 回答 1

1

不同的是,在方法 1 中,您对列表元素的类型一无所知;您可以对列表元素做的所有事情就是将它们视为Objects,例如

Object obj = list.get(0);

您甚至不能将此元素添加回列表中,因为无法保证列表的泛型类型是Object

List<Integer> list = new ArrayList<>(Arrays.asList(1));
method1(list);

void method1(List<?> list) {
  Object obj = list.get(0);
  list.add(obj);  // Compiler error! Can't add an Object to the List.
}

但是如果你使用类型变量,你可以这样做,因为编译器有关于它从列表中取出的元素的类型信息;它可以使用它来知道添加元素是安全的:

List<Integer> list = new ArrayList<>(Arrays.asList(1));
method2(list);

<T> void method2(List<T> list) {
  T obj = list.get(0);
  list.add(obj);  // OK!

  // But, if you discard the type information...
  Object obj1 = list.get(0);
  list.add(obj1);  // Still a compiler error.
}

擦除的类型T仍然是Object; 但是当编译器看到对 a 的引用时T,它可以知道它与列表元素的边界兼容。

于 2016-08-16T13:56:38.153 回答