从通用列表类型中获取Java类名称

时间:2014-01-24 09:31:38

标签: java generics generic-list

我有一个方法,里面有1个List,泛型类:

public static String classTypeOfList(List<T> list) {
    return T.getName(); //in my mind...
}

代码错了,但你可以看到,我想要的是什么。如果我这样称呼这个方法:

List<MyObject> list;
System.out.println("the type of the list is: "+classTypeOfList(list));

我想得到这个结果:

the type of the list is: MyObject

我怎样才能获得泛型类的名称?或者,如果我不能这样做,那么你能告诉我另一种选择吗? 谢谢!

5 个答案:

答案 0 :(得分:3)

由于Type Erasure,您将无法获取类型(如果是空列表)。正如JLS在类型擦除上所说:

<强> 4.6。键入Erasure

  

类型擦除是类型的映射(可能包括参数化)   类型和类型变量)到类型(从不参数化类型   或输入变量)。我们写| T |用于擦除T型   擦除映射定义如下:

The erasure of a parameterized type (§4.5) G<T1,...,Tn> is |G|.

The erasure of a nested type T.C is |T|.C.

The erasure of an array type T[] is |T|[].

The erasure of a type variable (§4.4) is the erasure of its leftmost bound.

The erasure of every other type is the type itself.
     

类型擦除还映射构造函数的签名(第8.4.2节)或   没有参数化类型或类型的签名的方法   变量。构造函数或方法签名的擦除是a   签名由与s相同的名称和所有的擦除组成   s中给出的形式参数类型。

     

构造函数或方法的类型参数(第8.4.4节)和   返回类型(§8.4.5)的一种方法,如果是,也会进行擦除   构造函数或方法的签名被删除。

     

删除泛型方法的签名没有类型   参数。

如果是非空清单:

......
public static void main(String[] args) throws ClassNotFoundException {

List<MyObject> list= new ArrayList<MyObject>();
        list.add(new MyObject());
        System.out.println("the type of the list is: "+classTypeOfList(list));
}

public static <T> String classTypeOfList(List<T> list) throws ClassNotFoundException {
        return list.get(0).getClass().getCanonicalName(); 
}

输出

the type of the list is: MyObject

答案 1 :(得分:2)

我害怕,这是做不到的。泛型仅在编译时存在。在运行时,此信息将被删除,在运行时,List<MyObject>将变为List

答案 2 :(得分:2)

这个答案可能与问题很少(或非常)不同,因为评论的时间足够长,所以我将其作为答案发布。

我发现这个问题很有趣,因此尝试了一下。我的尝试是关注,我得到了课程的Type,所以我认为值得分享,并获得专家对我的方法的意见

public class A {
    public static void main(String[] args) {

    List<B> listB = new ArrayList<>();
    B b1 = new B();
    listB.add(b1);

    List<C> listC = new ArrayList<>();
    C c1 = new C();
    listC.add(c1);

    A a = new A();
    a.method(listB);
    a.method(listC);

}

public <T> void method(List<T> list) {

    System.out.println(list.get(0).getClass().getName());
}
}

class B {

}

class C {

}

我得到的输出是BC

答案 3 :(得分:1)

您需要在对象上使用getClass()。获得类对象后,可以使用getName()检索类名。

答案 4 :(得分:0)

这是你可以上课的方法:

Class<T> clazz = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);

您可以在此link上阅读更多相关信息。