Java generics-получить класс? [дубликат]
этот вопрос уже есть ответ здесь:
у меня есть список, запрограммировать так: public class MyList<T>
. Есть ли способ использовать переменную T, чтобы получить имя класса (так что я могу, изнутри MyList
, знать, если T-строка, сокет и т. д.)?
изменить: Неважно, нашли ответ!--15-->здесь.
5 ответов:
короткий ответ:: ты не можешь.
ответ:
из-за того, как дженерики реализованы в Java, универсальный тип T не сохраняется во время выполнения. Тем не менее, вы можете использовать частный элемент данных:
public class Foo<T> { private Class<T> type; public Foo(Class<T> type) { this.type = type; } }
Мне нравится решение от
http://www.nautsch.net/2008/10/28/class-von-type-parameter-java-generics/
public class Dada<T> { private Class<T> typeOfT; @SuppressWarnings("unchecked") public Dada() { this.typeOfT = (Class<T>) ((ParameterizedType)getClass() .getGenericSuperclass()) .getActualTypeArguments()[0]; } ...
вы видите результат Стирания Типа. С этой страницы...
при создании экземпляра универсального типа, компилятор переводит эти типы с помощью метод стирания типа процесс, в котором компилятор удаляет все информация, связанная с параметрами типа и введите аргументы внутри класса или метод. Стирание типа включает Java приложения, использующие дженерики для поддерживать двоичную совместимость с Библиотеки и приложения Java что были созданы до дженериков.
например, Box
is переведено в поле типа, которое является называется необработанным типом-необработанный тип-это имя универсального класса или интерфейса без каких-либо аргументов типа. это означает что вы не можете узнать, какой тип Объект универсального класса используется в во время выполнения. Это выглядит так вопрос С очень хороший ответ, а также.
Я не на 100% уверен, что это работает во всех случаях (требуется хотя бы Java 1.5):
import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; public class Main { public class A { } public class B extends A { } public Map<A, B> map = new HashMap<Main.A, Main.B>(); public static void main(String[] args) { try { Field field = Main.class.getField("map"); System.out.println("Field " + field.getName() + " is of type " + field.getType().getSimpleName()); Type genericType = field.getGenericType(); if(genericType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) genericType; Type[] typeArguments = type.getActualTypeArguments(); for(Type typeArgument : typeArguments) { Class<?> classType = ((Class<?>)typeArgument); System.out.println("Field " + field.getName() + " has a parameterized type of " + classType.getSimpleName()); } } } catch(Exception e) { e.printStackTrace(); } } }
Это будет выход:
карта полей имеет тип Map
Карта полей имеет параметризованный тип a
Карта полей имеет параметризованный тип B
Я могу получить класс универсального типа таким образом:
class MyList<T> { Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(MyList.class, this.getClass()).get(0); }
вам нужно две функции из этого файла: http://code.google.com/p/hibernate-generic-dao/source/browse/trunk/dao/src/main/java/com/googlecode/genericdao/dao/DAOUtil.java
для более подробного объяснения:http://www.artima.com/weblogs/viewpost.jsp?thread=208860