Google Guice + generics: есть ли какое-то волшебство за занавесками? - PullRequest
4 голосов
/ 25 ноября 2011

Мне кажется, что реализация Guice делает некоторые очень хитрые вещи при работе с дженериками.Похоже, что знает во время выполнения об общих типах, используемых во время компиляции.Давайте рассмотрим простой пример:

@Inject
public void Bar(Provider<Foo> genericInjector){
...

Во время выполнения Guice внедрит правильную реализацию Provider здесь (то есть ту, которая предоставляет Foo экземпляров).Но из того, что я знаю, универсальные типы стираются во время выполнения (см .: Стирание типов ).Итак, все, что Guice действительно видит во время выполнения, это:

@Inject
public void Bar(Provider genericInjector){
....

Так как же возможно, что Guice знает, какую реализацию Provider ввести?

Ответы [ 2 ]

10 голосов
/ 25 ноября 2011

Нет, стирание типа не стирает все .Вы все еще можете получить типы полей, параметров и т. Д. Provider<Foo> информация равна , которая все еще присутствует во время выполнения.См., Например, Method.getGenericParameterTypes.

То, что не сохраняется, - это информация о типе конкретных объектов.Например, если я напишу:

List<String> list = new ArrayList<String>();
showType(list);

...


public static void showType(List<?> list)
{
    // ???
}

Невозможно понять, что это ArrayList<String>, потому что у объекта больше нет этой информации.

См. Часто задаваемые вопросы по Java Generics для лота больше информации.

2 голосов
/ 25 ноября 2011

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

Общие параметры не удаляются из сигнатур методов - сигнатуры методов - "время компиляции".Универсальные параметры не существуют в конструкциях «времени выполнения» - вы не можете сказать, с какими параметрами типа создан конкретный объект.

...