Как получитьзначение для Fooобъект? - PullRequest
6 голосов
/ 01 сентября 2010

(Это продолжение моего предыдущего вопроса )

У меня есть Foo<?> объект, foo. Foo<T> - это интерфейс.

Как получить значение типа, скрытое за <?>?

Обратите внимание, что это не тривиально, так как foo может быть, например, объектом класса Bar<String>, где Bar<T> implements Foo<T>, или некоторым интерфейсом реализации класса anonyomus FloatFoo, где FloatFoo extends Foo<Float>. Мне нужно решение, которое работает во всех случаях.

Заранее спасибо:)

Ответы [ 4 ]

9 голосов
/ 01 сентября 2010

Это невозможно при использовании отражения, поскольку в Java Generics существует проблема Тип Erasure .Во время выполнения типы, определенные для универсального класса Foo, были удалены, поэтому использование отражения для этого класса не приведет к его универсальному типу.Эта информация о типе используется только при компиляции для безопасности типов.

C # не имеет этой проблемы, и существует возможность доступа к шаблонному типу класса.

This обзор различий.

8 голосов
/ 01 сентября 2010

Ну, для краткости, вы не можете.

Однако вы можете получить значение <?> при использовании FloatFoo.

Действительно, насколько я помню, дженерики не хранятся в информации о классе.

однако, когда вы создаете подтип (будь то класс или интерфейс) универсального типа, информация об универсальных файлах должна быть запомнена, поскольку она может определять некоторые сигнатуры методов подтипа.

Например, если ваш Foo интерфейс объявлен так:

public interface Foo<T> {
    public T doIt();
}

Имея

public interface FloatFoo extends Foo<Float>

подразумевает, что этот интерфейс имеет

public Float doIt();

метод объявлен.

Для этого у компилятора должна быть информация о типе. И эта информация будет отражена в API отражения благодаря тому, что суперкласс FloatFoo будет иметь некоторые параметры Type, связанные с ним. Или, по крайней мере, это то, что я помню из тех немногих случаев, с которыми я сталкивался (или разрабатывал их, поскольку иногда это может быть обязательным)

Но у вас будет гораздо более полная информация на FAQ по дженерикам от Angelika .

2 голосов
/ 07 сентября 2010

Окончательно-окончательное (и, возможно, лучшее из возможных) решение: я реорганизовал свой код, поэтому он не нужен.Я переместил весь код, который нуждался в параметре типа, в Foo, чтобы я мог обеспечить соответствующую реализацию в классе.Оказалось, гораздо меньше кода.

1 голос
/ 03 сентября 2010

Я закончил с созданием метода getType() в интерфейсе:

Class<T> getType();

Возможно, это не самое элегантное решение, но определенно самое простое.

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