Java ClassCastException 从通用实例获取 ParameterizedType E "new ClazzXXX<E>()"
Java ClassCastException taking ParameterizedType E from generic instance "new ClazzXXX<E>()"
下面我粘贴了我想要的例子运行。
我可以轻松获得扩展 Home<String>
的 StringHome
实例的通用 class,但我无法对 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());
}
}
这个 class 的执行打印出这个:
String
StringBuilder
StringBuffer
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.command4j.core.commands.utils.Home.getTypeParameterClass(Home.java:13)
at org.command4j.core.commands.utils.Home.mainKO(Home.java:46)
at org.command4j.core.commands.utils.Home.main(Home.java:26)
你不能。
要理解这一点,只需为每个对象的层次结构制作一棵树。
- StringHome 的超类是 Home
<java.lang.String>
。因此,当您调用 getGenericSuperclass() 时,您将获得该超类。然后就可以得到实际的类型参数String.
但是
- Home
<String>
的超类是 java.lang.Object 。此外,在运行时,您丢失了参数并且只能知道它是一个 Home 对象。
Java 泛型在编译时擦除泛型类型信息。您将无法在运行时获取此信息。
下面我粘贴了我想要的例子运行。
我可以轻松获得扩展 Home<String>
的 StringHome
实例的通用 class,但我无法对 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());
}
}
这个 class 的执行打印出这个:
String
StringBuilder
StringBuffer
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at org.command4j.core.commands.utils.Home.getTypeParameterClass(Home.java:13)
at org.command4j.core.commands.utils.Home.mainKO(Home.java:46)
at org.command4j.core.commands.utils.Home.main(Home.java:26)
你不能。
要理解这一点,只需为每个对象的层次结构制作一棵树。
- StringHome 的超类是 Home
<java.lang.String>
。因此,当您调用 getGenericSuperclass() 时,您将获得该超类。然后就可以得到实际的类型参数String.
但是
- Home
<String>
的超类是 java.lang.Object 。此外,在运行时,您丢失了参数并且只能知道它是一个 Home 对象。
Java 泛型在编译时擦除泛型类型信息。您将无法在运行时获取此信息。