дженерики, сигнатуры методов, назначения - PullRequest
2 голосов
/ 19 февраля 2010

Я думал, что понял это, но, очевидно, нет ...

У меня есть подпись метода, например, так:

void doSomething(List<TypeA> typeAs){...}

List<TypeA<TypeB>> getTypeBTypeAs(){...}

но если я попытаюсь позвонить

doSomething(getTypeBTypeAs());

Я получаю ошибку компиляции: «метод doSomething (List) в типе ... не применим для аргументов (List>)»

однако, если я изменю сигнал doSomething на

void doSomething(List<TypeA<?>> typeAs){...}

это все еще не работает, но

void doSomething(List typeAs){...}

очевидно, что это работает, как я обойти дженерики.

что странно.

Может кто-нибудь заполнить меня?

Кроме того, в этом случае я бы хотел, чтобы doSomething работал с любым списком, содержащим TypeAs любого универсального типа; undefined, TypeB, TypeC и т. д.

спасибо.

Ответы [ 2 ]

4 голосов
/ 19 февраля 2010

Универсальный класс TypeA<TypeB> отличается от TypeA.Вы не можете передать параметр типа TypeA<TypeB>, где метод ожидает TypeA.Также TypeA<TypeB> отличается от типа TypeA<TypeC>, поэтому применяются те же ограничения.

Классический пример (из Effective Java, 2nd Ed. AFAIR): у нас есть контейнеры дляживотные (Container<Animal>) и в качестве подклассов Animal мы имеем Lion и Butterfly.Теперь, если у вас есть метод

void func(Animal animal);

, он будет принимать и львов, и бабочек.Однако эта функция

void func(Container<Animal> animalContainer);

не будет принимать ни Container<Lion>, ни Container<Butterfly>.Поймите, что прочная клетка, полезная для безопасного содержания львов, не помешает бабочкам улететь, и наоборот, толстая, но легкая сеть для удержания бабочек не будет иметь шансов против льва.

Если вы действительно уверенычто любой вид контейнера для животных подходит вам, объявите вашу функцию следующим образом:

void func(Container<? extends Animal> animalContainer);

Вернемся к вашему случаю, я думаю, что единственный способ принять оба List<TypeA> и List<TypeA<TypeB>> будет выглядеть примерно так:

void doSomething(List<?> list);
0 голосов
/ 19 февраля 2010

Попробуйте это:

<T> void doSomething(List<TypeA<T>> typeAs) { ... }

Обратите внимание на <T> в начале строки. Таким образом, doSomething принимает каждый список, содержащий любые TypeAs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...