2014-08-27 2 views
4

Объясняя этот вопрос на примере:Java дженериков: Неограниченные подстановочные не работает с типом Object аргумента

public class DataWrapper<T> { 
    T data; 
}; 

DataWrapper<Object> obj1 = new DataWrapper<Object>(); 

List<DataWrapper<?>> anyDataList = Arrays.asList(obj1); //this doesn't work 

DataWrapper<Integer> objInt = new DataWrapper<Integer>(); 
anyDataList = Arrays.asList(obj1, objInt); //this work 

Я не мог понять, почему «Arrays.asList (obj1)» не работает?

+4

Обновления до Java 8 для лучшего результата :) –

+0

системы Типа Java довольно трудно кода вокруг без IDE, это точно. –

+0

Подтверждено: это работает на Java 8 – therealrootuser

ответ

9

Java 7 был глуп (а не был) при выводе аргументов типа для общих методов. Например, он будет использовать объявленный тип аргумента для вывода типа независимо от контекста вызова метода. Таким образом, в

Arrays.asList(obj1); 

аргумент типа будет выведен в

DataWrapper<Object> 

метод; тип возвращаемого значения будет затем List<DataWrapper<Object>> который не является назначаемым на List<DataWrapper<?>>.

В

Arrays.asList(obj1, objInt); 

тип выводится из обоих аргументов. Между ними обнаружен общий тип. В этом случае это ? extends Object. Возвращаемый тип метода становится List<DataWrapper<? extends Object>>, который присваивается List<DataWrapper<?>>.

В Java 8 то, что вы разместили, работает из коробки. В Java 7, вы можете предоставить явный аргумент типа, чтобы заставить его работать

List<DataWrapper<?>> anyDataList = Arrays.<DataWrapper<?>>asList(obj1); 
+0

+1 для объяснения. Можете ли вы также предоставить обходной путь для людей, использующих Java 7? – StriplingWarrior

+1

@ StriplingWarrior Yup, добавлено. Благодаря! –

+0

DataWrapper может быть назначен DataWrapper . Расширяя эту логику, я ожидал, что шаблон будет работать и для вложенных параметров второго уровня: List > должен быть назначен List > – user1447561

Смежные вопросы