Подтвердить что ты не робот

Java generics - получить класс?

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

EDIT: Nevermind, нашел ответ здесь.

4b9b3361

Ответ 1

Короткий ответ. Вы не можете.

Длинный ответ:

Из-за того, как генерические средства реализованы в Java, общий тип T не сохраняется во время выполнения. Тем не менее, вы можете использовать частный элемент данных:

public class Foo<T> 
{
    private Class<T> type;

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

Ответ 3

Вы видите результат Тип Erasure. С этой страницы...

Когда генерируется типичный тип, компилятор переводит эти типы метод, называемый стиранием стилей - a процесс, когда компилятор удаляет все информация, относящаяся к параметрам типа и введите аргументы внутри класса или метод. Тип erasure позволяет Java приложения, которые используют поддерживать двоичную совместимость с Java-библиотеки и приложения, которые были созданы до дженериков.

Например, Box <String> является переведенный в тип Box, который называемый необработанным типом - необработанный тип общий класс или имя интерфейса без аргументов типа. Это означает что вы не можете узнать, какой тип Объект, используемый универсальным классом во время выполнения.

Это также выглядит как question, у которого есть неплохой ответ.

Ответ 4

Я не уверен на 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

Ответ 5

Я могу получить класс универсального типа следующим образом:

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