代码之家  ›  专栏  ›  技术社区  ›  brunov

如何获取参数化类实例

  •  9
  • brunov  · 技术社区  · 17 年前

    由于引入了泛型,类被参数化,因此list.class生成class<list>。这很清楚。

    我无法理解的是如何获取类型为的类的实例,该类本身是参数化的,即class<list<string>。就像这段话:

    public class GenTest {
        static <T> T instantiate(Class<T> clazz) throws Exception {
            return clazz.newInstance();
        }
        public static void main(String[] args) throws Exception {
            // Is there a way to avoid waring on the line below
            // without using  @SuppressWarnings("unchecked")?
            // ArrayList.class is Class<ArrayList>, but I would like to
            // pass in Class<ArrayList<String>>
            ArrayList<String> l = GenTest.instantiate(ArrayList.class);
        }
    }
    

    我经常遇到这个问题的变化,我仍然不知道,如果我错过了什么,或者如果真的没有更好的方法。谢谢你的建议。

    4 回复  |  直到 13 年前
        1
  •  8
  •   Avi    17 年前

    类类是类型的运行时表示形式。由于参数化类型在运行时进行类型擦除,因此类的类对象将与类<list<integer>和类<list<string>的类对象相同。

    无法使用.class表示法实例化它们的原因是,这是用于类文本的特殊语法。这个 Java Language Specification 特别禁止在类型参数化时使用此语法,这也是不允许使用List<String>.Class的原因。

        2
  •  1
  •   Tom Hawtin - tackline    17 年前

    类表示类加载器加载的类,这些类是原始类型。要表示参数化类型,请使用java.lang.reflect.ParameterizedType。

        3
  •  1
  •   Dan Dyer    17 年前

    我认为你做不到你想做的。首先,您的实例化方法不知道它处理一个参数化的类型(您可以轻松地通过Java.UTI.Deal.Class)。其次,由于擦除,在运行时对参数化类型执行任何特定的操作都是困难的或不可能的。

    如果您要以不同的方式处理问题,您还可以使用其他一些小技巧,例如类型推断:

    public class GenTest
    {
        private static <E> List<E> createList()
        {
            return new ArrayList<E>();
        }
    
        public static void main(String[] args)
        {
            List<String> list = createList();
            List<Integer> list2 = createList();
        }
    }
    
        4
  •  0
  •   thSoft    13 年前

    你唯一能做的就是实例化 List<String> 直接地 并调用它的 getClass() :

    instantiate(new List<String>() { ... }.getClass());
    

    对于具有多种抽象方法的类型,如 List 这很尴尬。但不幸的是,调用子类构造函数(如 new ArrayList<String> )或工厂方法( Collections.<String>emptyList() 不要工作。