Java ClassCastException从通用实例“new ClazzXXX <e>()”获取ParameterizedType E

时间:2016-07-01 14:49:50

标签: java class generics generic-programming parametric-polymorphism

下面我粘贴了我想要运行的示例。

我可以轻松获取扩展StringHome的{​​{1}}实例的泛型类,但我不能对Home<String>实例执行相同操作。 我怎样才能获得它?

我的目标是使new Home<String>()方法与mainKO一样有效。

mainOK

这个类的执行打印出来:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Home<E> {
    @SuppressWarnings ("unchecked")
    public Class<E> getTypeParameterClass(){
        Type type = getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        return (Class<E>) paramType.getActualTypeArguments()[0];
    }

    private static class StringHome extends Home<String>{}
    private static class StringBuilderHome extends Home<StringBuilder>{}
    private static class StringBufferHome extends Home<StringBuffer>{}   

    public static void main(String[] args) throws Exception {
        // this works fine
        mainOK();
        Thread.sleep(1000);
        // this throws an error
        mainKO();
    }

    /**
     * This prints "String", "StringBuilder" and "StringBuffer"
     */
    public static void mainOK() throws Exception {
        Object object0 = new StringHome().getTypeParameterClass().newInstance();
        Object object1 = new StringBuilderHome().getTypeParameterClass().newInstance();
        Object object2 = new StringBufferHome().getTypeParameterClass().newInstance();
        System.out.println(object0.getClass().getSimpleName());
        System.out.println(object1.getClass().getSimpleName());
        System.out.println(object2.getClass().getSimpleName());
    }

    /**
     * This throws error:
     * Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
     */
    public static void mainKO() throws Exception {
        Object object0 = new Home<String>().getTypeParameterClass().newInstance();
        Object object1 = new Home<StringBuilder>().getTypeParameterClass().newInstance();
        Object object2 = new Home<StringBuffer>().getTypeParameterClass().newInstance();
        System.out.println(object0.getClass().getSimpleName());
        System.out.println(object1.getClass().getSimpleName());
        System.out.println(object2.getClass().getSimpleName());
    }
}

1 个答案:

答案 0 :(得分:2)

你不能

要理解这一点,只需为每个对象的层次结构创建一个树。

  • StringHome 的超类 主页<java.lang.String> 。因此,当您调用getGenericSuperclass()时,您将获得该超类。然后,您可以获取实际的类型参数 String

<强> BUT

  • 主页<String> 的超类是 java.lang.Object 。此外,在运行时,您丢失了参数,只是知道它是 Home 对象。

Java泛型擦除编译时的泛型类型信息。您无法在运行时获取此信息。