Получить универсальный тип класса во время выполнения

JS Fiddle: http://jsfiddle.net/eyedean/1bw357kw/

popFileSelector = function() {
    var el = document.getElementById("fileElem");
    if (el) {
        el.click();  
    }
};

window.popRightAway = function() {
    document.getElementById('log').innerHTML += 'I am right away!
'; popFileSelector(); }; window.popWithDelay = function() { document.getElementById('log').innerHTML += 'I am gonna delay!
'; window.setTimeout(function() { document.getElementById('log').innerHTML += 'I was delayed!
'; popFileSelector(); }, 1000); };

  
Pop Now
Pop With 1 Second Delay
Log:

445
задан ROMANIA_engineer 26 December 2015 в 16:56
поделиться

8 ответов

Я сделал то же как @Moesio Выше, но в Kotlin оно могло быть сделано этот путь:

class A<T : SomeClass>() {

    var someClassType : T

    init(){
    this.someClassType = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
    }

}
0
ответ дан 22 November 2019 в 22:49
поделиться

Как уже упоминалось, это возможно только через отражение в определенных обстоятельствах.

Если вам действительно нужен тип, это обычный (безопасный для типов) шаблон обхода:

public class GenericClass<T> {

     private final Class<T> type;

     public GenericClass(Class<T> type) {
          this.type = type;
     }

     public Class<T> getMyType() {
         return this.type;
     }
}
298
ответ дан 22 November 2019 в 22:49
поделиться

Я не думаю, что вы можете, Java использует стирание типов при компиляции, поэтому ваш код совместим с приложениями и библиотеками, которые были созданы до дженериков.

Из Oracle Docs:

Type Erasure

В язык Java были введены обобщения, чтобы обеспечить более плотный тип проверяет во время компиляции и поддерживает универсальное программирование. К реализовать универсальные типы, компилятор Java применяет стирание типа к:

Заменять все параметры типа в универсальных типах их границами или Возражать, если параметры типа неограниченны. Созданный байт-код, следовательно, содержит только обычные классы, интерфейсы и методы. При необходимости вставьте типовые отливки для сохранения типовой безопасности. Генерировать мостовые методы для сохранения полиморфизма в расширенных универсальных типах.Стирание типа гарантирует, что не будут созданы новые классы для параметризованных типы; следовательно, универсальные шаблоны не несут накладных расходов во время выполнения.

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

15
ответ дан 22 November 2019 в 22:49
поделиться

Вы не можете. Если вы добавите в класс переменную-член типа T (вам даже не нужно ее инициализировать), вы можете использовать ее для восстановления типа.

4
ответ дан 22 November 2019 в 22:49
поделиться

Generics не reified во время выполнения. Это означает, что информация не присутствует во время выполнения.

Добавление дженериков в Java при сохранении обратной совместимости стало настоящим прорывом (вы можете ознакомиться с основополагающей статьей об этом: Making the future safe for the past: adding genericity to the Java programming language).

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

90
ответ дан 22 November 2019 в 22:49
поделиться

Конечно, вы можете.

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

Из официального API:

http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments%28%29

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

37
ответ дан 22 November 2019 в 22:49
поделиться

Java generics в основном компилируются, это означает, что информация о типе теряется во время выполнения.

class GenericCls<T>
{
    T t;
}

будет скомпилировано в нечто вроде

class GenericCls
{
   Object o;
}

Чтобы получить информацию о типе во время выполнения, вы должны добавить ее в качестве аргумента ctor.

class GenericCls<T>
{
     private Class<T> type;
     public GenericCls(Class<T> cls)
     {
        type= cls;
     }
     Class<T> getType(){return type;}
}

Example:

GenericCls<?> instance = new GenericCls<String>(String.class);
assert instance.getType() == String.class;
34
ответ дан 22 November 2019 в 22:49
поделиться

Я видел что-то подобное

private Class<T> persistentClass;

public Constructor() {
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                            .getGenericSuperclass()).getActualTypeArguments()[0];
 }

в hibernate GenericDataAccessObjects Пример

244
ответ дан 22 November 2019 в 22:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: