Любой способ сделать общий список, где я могу добавить тип и подтип? - PullRequest
1 голос
/ 06 января 2011

Я понимаю, почему я не могу сделать следующее:

private class Parent {
};

private class Child extends Parent {
};

private class GrandChild extends Child {
};

public void wontCompile(List<? extends Parent> genericList, Child itemToAdd) {
    genericList.add(itemToAdd);
}

У меня есть вопрос, есть ли ЛЮБОЙ практический способ иметь типизированный список, в котором вы можете позвонить add (E), где известно, что E - это только родитель или ребенок?

Я смутно помню какое-то использование "|" оператор, используемый для подстановочных знаков, но я не могу найти его в спецификации ...

Спасибо!

Ответы [ 3 ]

0 голосов
/ 06 января 2011

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

Это было бы ужасно и, скорее всего, ужасная идея.

0 голосов
/ 13 ноября 2012

Почему бы и нет?Все, что вам нужно, - это соответствующий универсальный тип для аргументов List и item, который удовлетворяет обоим параметрам вызова, вы можете добиться этого довольно просто:

import java.util.ArrayList;
import java.util.List;

public class TestClass {

  private class Parent {
  };

  private class Child extends Parent {
  };

  private class GrandChild extends Child {
  };

  public <T extends Parent> void compilesNow(final List<T> genericList, final T itemToAdd) {
    genericList.add(itemToAdd);
  }

  public void addSomeDescendents() {
    final List<Parent> list = new ArrayList<Parent>();
    compilesNow(list, new Parent());
    compilesNow(list, new Child());
    compilesNow(list, new GrandChild());
  }
}

EDIT: Извините, я пропустил бит об исключении GrandChild ..Однако мой пример - это шаг вперед к тому, как можно использовать Generics, чтобы этот сценарий хотя бы компилировался

0 голосов
/ 06 января 2011

Нет.

В add(E) определение точного типа E может быть сделано только во время выполнения.Любая переменная, объявленная как тип Parent, может содержать ссылку на объект GrandChild из-за отношения подтипа;нет способа создать список, в котором вы не можете добавлять объекты подтипа типа элемента (по крайней мере, когда такая операция будет запрещена компилятором).

реальный вопрос: почему ты вообще этого хочешь?Возможно, ваша иерархия наследования перевернута.

...