Получить "настоящий" класс родового типа
Как я могу получить "настоящий" класс общего типа?
Пример:
public class MyClass<T> {
public void method(){
//something
System.out.println(T.class) //causes a compile error, I wont the class name
//something
}
}
Если T = целое число
Вывод:
java.lang.Integer
Если T = String
Вывод:
java.lang.String
Спасибо
Ответы
Ответ 1
Если у вас есть переменная экземпляра типа T в вашем классе, и она, вероятно, будет установлена, то вы можете напечатать класс этой переменной.
public class Test<T> {
T var;
public static void main(String[] args) {
Test<Integer> a = new Test<Integer>();
System.out.println(a.boo());
a.setVar(new Integer(10));
System.out.println(a.boo());
}
public String boo() {
if (var == null) {
return "Don't know yet";
}
return var.getClass().getSimpleName();
}
public void setVar(T var) {
this.var = var;
}
public T getVar() {
return var;
}
}
Ответ 2
Вы не можете. Информация удаляется из кода во время компиляции, процесс, известный как стирание типа. Подробнее см. Здесь Тип Erasure
Изменить: извините, мой плохой, информация не загружается во время выполнения.
Ответ 3
Как объяснили другие, вы не можете сделать это таким образом, но это так обычно достигается в java.
public class MyClass<T> {
public void method(Class<T> clazz) {
// something
System.out.println(clazz.getName());
// something
}
}
и вы используете его как это
new MyClass<String>().method(String.class);
Ответ 4
В случае вашей ситуации вы не можете. Тем не менее, вы можете использовать токены Super Type для этого типа вещей: http://gafter.blogspot.com/2006/12/super-type-tokens.html
Примером реализации является класс TypeReference библиотеки обработки Jackson json.
Это продвинутый материал и, вероятно, больше, чем вы хотели знать; -)
Ответ 5
Обратите внимание, что подходы, основанные на 'getClass()' на экземпляре, полученном с помощью универсального типа, получат фактический тип этого объекта, что не обязательно является общим типом - это будет тот тип, по которому вызывающий пользователь знал экземпляр.
Например, рассмотрим случай, когда вызывающий объект обрабатывает объект интерфейсом; при переходе к родовым конструкциям общий тип будет интерфейсом, а не фактическим классом экземпляра.
Рассмотрим следующий пример класса "Пара", который позволяет возвращать две ссылки на объекты через POJO:
public class Pair<U,V>
{
public final U first;
public final V second;
public static <U,V> Pair<U,V> of (U first, V second)
{
return new Pair<U,V> (first, second);
}
protected Pair (U first, V second)
{
this.first = first;
this.second = second;
}
}
Мы рассматривали, как изменить функцию "Pair.of()" factory, чтобы вернуть производный класс Comparable Pair, если U и V были сопоставимыми. Однако, хотя мы можем определить, сопоставимы ли "первый" и "второй" с использованием instanceof, мы не знаем, что сами U и V являются сопоставимыми.
Чтобы это сработало, точный тип пары, возвращаемый параметром Pair.of(), должен зависеть от общих типов, а не от фактических типов аргументов.