Java: управление списками с помощью суперклассов - PullRequest
0 голосов
/ 12 августа 2010

Предположим, у меня есть MyEdge и MyEdgeModified, так что MyEdge - это суперкласс, а MyEdgeModified - это подкласс.Теперь предположим, что я делаю это:

List<List<MyEdge>> collectionOfEdgeLists = new LinkedList<List<MyEdge>>();
for(int i = 0; i < someValue; i++) {
    List<MyEdgeModified> newList = someMethod();
    collectionOfEdgeLists.add(newList); //ruh roh
}

Теперь, если я сделаю это:

private List<MyEdge> convert(final List<MyEdgeModified> list) {
     final List<MyEdge> otherList = new ArrayList<MyEdge>(list.size());
     for(Edge edge : list) {
         otherList.add(edge);
     }
     return otherList;
}

Тогда:

collectionOfEdgeLists.add(convert(newList)); //ok...

Теперь проблема в том, что яздесь я могу рассматривать каждого человека MyEdgeModified как Edge, но если у меня есть коллекция, я должен сначала создать целый «другой список», чтобы иметь возможность использовать его.Зачем?Я делаю что-то неправильно?Это кажется мне неправильным и глупым.

Ответы [ 2 ]

3 голосов
/ 12 августа 2010

Рассмотрим этот код:

List<MyEdgeModified> modifiedList = new List<MyEdgeModified>();

// This is what you want to do, but which doesn't work
List<MyEdge> edgeList = modifiedList;

// Now this would have to be valid...
edgeList.add(new MyEdge());

// And this should be valid too...
MyEdgeModified modified = modifiedList.get(0);

... но вам удалось поместить ссылку на экземпляр MyEdge в List<MyEdgeModified> - так что вам удалось нарушить безопасность типов.

Вот какие правила существуют для предотвращения.

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

List<MyEdgeModified> modifiedList = new List<MyEdgeModified>();
List<? extends MyEdge> edgeList = modifiedList;

В этот моментВы не сможете добавить к edgeList, но вы можете взять у него предметы ... так что все в порядке.

Теперь создание List<List<? extends MyEdge>> оказывается сложнееопять же ... я не могу вспомнить наизусть, разрешено ли это вообще ...

В общем, лучшее место, где можно найти подробности такого рода вещей, это FAQ Дженелики Лангер по Java Generics .

2 голосов
/ 12 августа 2010

Это связано с отсутствием ковариации в дженериках Java.

Ковариация означает, что для некоторого типа T и подтипа S, List<S> является подтипом List<T>.

Это не так в Java. Для рассуждения предположим, что ковариация существует, и рассмотрим следующий случай:

List<String> stringList = new ArrayList<String>();
List<Object> oList = stringList; // Just referring to a subtype as its supertype
oList.add(new Object()); // nothing wrong with adding an Object to a List<Object>
for (String s : stringList) { ... }  // now what?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...