LINUX.ORG.RU

Generics in Java

 ,


0

1

Привет! Возник вопрос по generics и type erasure.

public class GenericEntity<K> {
    private K key;
    private List<String> list;
}

public class Examples {
    private static List<String> getList(final GenericEntity entity) {
        return entity.getList();  //warning here
    }

    private static List<String> getList(final GenericEntity<Integer> entity) {
        return entity.getList();  // all ok
    }
}

Не очень понимаю, почему когда я пытаюсь достать List - у меня на этом месте warning про то, что result of getList() is erased.

Если бы я доставал key - я бы понял, но тут мне кажется как-то странно это.

Прошу консультации:)


Ответ на: комментарий от ThePretender

Спасибо за ответ. Но тут-то понятно, мы raw type пытаемся присвоить параметризованному, здесь ясно откуда warning, но в моем примере же не так.

Я из raw type беру элемент, который с самого начала параметризован, и получаю warning.

Ваш пример - понял, но ответ на свой вопрос не нашел.

aarexer
() автор топика

помойму использование raw type, и особенно - присваивание нейпойми чего параметризованному типу - это ересь, и дальнейшее обсуждение просто не имеет смысла

зачем тебе нужно так писать?

stevejobs ★★★★☆
()
Ответ на: комментарий от aarexer

при виде «raw type» jvm включает «режим совместимости» и все генерики из этого объекта превращаются в тыкву.

ps. по ссылке кстати все написано:

Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects.
You also get a warning if you use a raw type to invoke generic methods defined in the corresponding generic type:

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от aarexer

но в моем примере же не так.

да ну? ты raw type пытаешься присваивать параметризованному (List<String>) результату функции getList

попробуй не делать этого присваивания, и ворнинг должен исчезнуть

    private static List<String> getList(final GenericEntity entity) {
        Object x = entity.getList();  //no warning here
        return null;
    }
stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от Deleted

Понял, да, значит при raw type у нас вообще все в объекте трется, даже то, что явно параметризовано

aarexer
() автор топика
Ответ на: комментарий от stevejobs

Спасибо! Не знал просто, что все внутри трется при raw type

aarexer
() автор топика
Ответ на: комментарий от aarexer

Понял, да, значит при raw type у нас вообще все в объекте трется, даже то, что явно параметризовано

Не трётся, а просто включается режим совместимости, как будто у тебя нет никаких генериков в языке. И Type Erasure это совсем другое, а не то, что ты написал.

Legioner ★★★★★
()
Ответ на: комментарий от aarexer

Слегка поздно, но вариант решения:

    private static List<String> getList(final GenericEntity<?> entity) {
        return entity.getList();
    }

sargeman
()
Ответ на: комментарий от aarexer

Type Erasure это стирание типов в рантайме. В Java есть reflection. Ты можешь в рантайме узнать тип объекта. Например l instanceof List. Но информация о параметрах обобщённого класса не сохраняется, поэтому нельзя отличить l instanceof List<String> от l instanceof List<Integer>, например.

А при компиляции информация о типах доступна, если конечно осознанно её не отключать, как в твоём примере.

Legioner ★★★★★
()

Всем спасибо за помощь!

aarexer
() автор топика
Ответ на: комментарий от Legioner

А для каких целей вообще существует этот Type Erasure? Я просто на шарпе пишу. Для меня такие фичи, которые превращают данные в какашку от одной очепятки выглядят очень уж странно.

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

Ну для совместимости, раньше же generic-ов не было

aarexer
() автор топика
Ответ на: комментарий от nikolnik

Фиг его знает, самому интересно :) Про совместимость не то, мало ли что раньше не было, код от нового компилятора на старой JVM и так не запустится. Но про опечатку ты погорячился, код без generic-ов вызывает предупреждения, поэтому там надо не только опечататься, но и закрыть глаза на предупреждения.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

для совместимости старых сорцов в которых нет генериков, а не бинарной

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.