Почему метод не может взять коллекцию <subClass>, если сигнатура метода определена как коллекция <class> - PullRequest
6 голосов
/ 06 августа 2011

У меня есть метод, который принимает список объектов SResource

public static List<STriple> listTriples(List<SResource> subjects){
//... do stuff
}

Почему я не могу сделать это

List<IndexResource> resultsAsList = new ArrayList<IndexResource>();
    resultsAsList.addAll(allResults.keySet()); // I could possible not use lists and just use sets and therefore get rid of this line, but that is a different issue
List<STriple> triples = new ArrayList<STriple>();
    triples = TriplesDao.listTriples(resultsAsList);

(Компилятор говорит мне, что я должен сделать triples используйте объекты SResource.)

Когда IndexResource является подклассом SResource

public class IndexResource extends SResource{ 
// .... class code here
}

Я бы подумал, что это возможно, поэтому, возможно, я делаю что-то еще неправильно.Я могу опубликовать больше кода, если вы предложите это.

Ответы [ 3 ]

23 голосов
/ 06 августа 2011

Вы можете сделать это, используя подстановочные знаки :

public static List<STriple> listTriples(List<? extends SResource> subjects){
    //... do stuff
}

В новом объявлении используется ограниченный подстановочный знак , который говорит, что универсальным параметром будет либо SResource, либо тип, расширяющий его.

В обмен на принятие List<> таким способом «делать вещи» не может включать вставку в subjects. Если вы просто читаете из subjects в методе, то это изменение должно дать вам желаемые результаты.

РЕДАКТИРОВАТЬ : Чтобы понять, почему нужны символы подстановки, рассмотрите этот (недопустимый в Java) код:

List<String> strings = new ArrayList<String>();
List<Object> objList = string; // Not actually legal, even though string "is an" object
objList.add(new Integer(3)); // Oh no! We've put an Integer into an ArrayList<String>!

Это явно не типично безопасно. Однако с открытками вы можете сделать это:

List<String> strings = new ArrayList<String>();
string.add("Hello");
List<? extends Object> objList = strings; // Works!
objList.add(new Integer(3)); // Compile-time error due to the wildcard restriction
6 голосов
/ 06 августа 2011

Вы не можете сделать это, потому что дженерики не являются "ковариантными" , т.е. List<Integer> не является подклассом List<Number>, хотя Integer является подклассом Number.

1 голос
/ 28 июня 2016

Для тех, кто не может добавлять символы подстановки, это должно работать.

List<Integer> list = new ArrayList<Integer>();
new ArrayList<Number>(list);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...