2016-08-16 3 views
-1

Почему Java предоставила Unbounded wild card, если мы сможем решить проблему, используя Generic type. НапримерВ чем разница между использованием Unbounded wild card и типа Generic в Java?

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); 
     } 
    } 
} 

Может кто-нибудь, пожалуйста, помогите мне понять, если метод 2 может решить наши требования, то почему мы должны иметь метод 1. Средство, проблема которого может быть решена с помощью неограниченного подстановочного знака и которая не может быть решена с использованием метода общего типа (например, метода 2)?

+2

Вы можете добавить элементы в 'list' в методе 2; вы не можете в методе 1. –

+0

Спасибо @AndyTurner, но если добавление элемента является единственной проблемой, мы можем изменить его ниже кода snippet public static void methodWithType (Список )) { для (Object obj: list) { System.out.println (obj); } } – MishraJi

+0

Это не единственная проблема; это всего лишь пример проблемы, в которой переменная типа предоставляет достаточную информацию, чтобы компилятор мог гарантировать безопасность. –

ответ

1

Разница в том, что в методе 1 вы ничего не знаете о типе элементов списка; все, что вы можете сделать с элементами списка, - обрабатывать их, например, Object s, например.

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; но когда компилятор видит ссылку на T, он может знать, что он совместим с границами элементов списка.