Почему меня должно волновать, что в Java нет усовершенствованных обобщений? - PullRequest
101 голосов
/ 18 декабря 2009

Это возникло как вопрос, который я недавно задал в интервью, как то, что кандидат хотел видеть добавленным к языку Java. Это обычно называют болью в том, что у Java нет усовершенствованных дженериков , но, когда его выдвинули, кандидат не мог на самом деле сказать мне, чего он мог достичь, если бы он был там.

Очевидно, что необработанные типы допустимы в Java (и небезопасные проверки), возможно подорвать дженерики и в итоге получить List<Integer>, который (например) фактически содержит String с. Это явно можно было бы сделать невозможным, если бы информация о типах была усовершенствована; но должно быть и больше !

Могут ли люди опубликовать примеры вещей, которые они действительно хотели бы сделать , были ли доступны дженерики? Я имею в виду, очевидно, вы могли бы получить тип List во время выполнения - но что бы вы сделали с ним?

public <T> void foo(List<T> l) {
   if (l.getGenericType() == Integer.class) {
       //yeah baby! err, what now?

РЕДАКТИРОВАТЬ : Быстрое обновление этого, поскольку ответы, по-видимому, в основном касаются необходимости передачи Class в качестве параметра (например, EnumSet.noneOf(TimeUnit.class)). Я больше искал что-то вроде , где это просто невозможно . Например:

List<?> l1 = api.gimmeAList();
List<?> l2 = api.gimmeAnotherList();

if (l1.getGenericType().isAssignableFrom(l2.getGenericType())) {
    l1.addAll(l2); //why on earth would I be doing this anyway?

Ответы [ 13 ]

2 голосов
/ 18 декабря 2009

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

Мое мнение таково, что дженерики - это просто дополнительный , который экономит много избыточного приведения.

0 голосов
/ 19 августа 2017

То, что все ответы здесь пропущены, что для меня постоянно является головной болью, так как типы стираются, вы не можете наследовать универсальный интерфейс дважды. Это может быть проблемой, если вы хотите создать детализированные интерфейсы.

    public interface Service<KEY,VALUE> {
           VALUE get(KEY key);
    }

    public class PersonService implements Service<Long, Person>,
        Service<String, Person> //Can not do!!
0 голосов
/ 16 октября 2011

Вот тот, который поймал меня сегодня: без reification, если вы напишите метод, который принимает список общих элементов varargs ... вызывающие абоненты могут ДУМАТЬ, что они безопасны, но случайно передать любой старый код и взорвать ваш способ.

Кажется маловероятным, что это произойдет? ... Конечно, пока ... вы не используете Class в качестве своего типа данных. На этом этапе ваш вызывающий абонент с радостью отправит вам множество объектов Class, но простая опечатка отправит вам объекты Class, которые не соответствуют T, и ударам.

(NB: Возможно, я допустил здесь ошибку, но, погуглив вокруг "generics varargs", вышеприведенное, кажется, именно то, что вы ожидаете. То, что делает это практической проблемой, это использование Class, я думаю - кажется, что абоненты менее осторожны :()


Например, я использую парадигму, которая использует объекты класса в качестве ключа на картах (это более сложно, чем простая карта - но концептуально это то, что происходит).

например. это прекрасно работает в Java Generics (тривиальный пример):

public <T extends Component> Set<UUID> getEntitiesPossessingComponent( Class<T> componentType)
    {
        // find the entities that are mapped (somehow) from that class. Very type-safe
    }

например. без определения в Java Generics, этот принимает ЛЮБОЙ объект "Класс". И это только крошечное расширение предыдущего кода:

public <T extends Component> Set<UUID> getEntitiesPossessingComponents( Class<T>... componentType )
    {
        // find the entities that are mapped (somehow) to ALL of those classes
    }

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

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