Java generics-получить класс? [дубликат]


этот вопрос уже есть ответ здесь:

у меня есть список, запрограммировать так: public class MyList<T>. Есть ли способ использовать переменную T, чтобы получить имя класса (так что я могу, изнутри MyList, знать, если T-строка, сокет и т. д.)?

изменить: Неважно, нашли ответ!--15-->здесь.

5 65

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