0

Ниже я вставил пример, который я хотел бы запустить.Java ClassCastException, берущий ParameterizedType E из общего экземпляра "new ClazzXXX <E>()"

Я могу легко получить общий класс экземпляра StringHome, который расширяет 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()); 
    } 
} 

Выполнение этого класса печатает это:

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) 
+2

Вы просто не можете. –

+0

Можете ли вы объяснить мне, почему это невозможно технически? – madx

ответ

2

Вы не можете.

Чтобы понять это, просто создайте дерево каждой иерархии вашего объекта.

  • StringHome «s суперкласс Главная <java.lang.String>. Поэтому, когда вы вызываете getGenericSuperclass(), вы получаете этот суперкласс. Затем вы можете получить фактический параметр типа String.

НО

  • Главная <String> «s суперкласс java.lang.Object. Кроме того, во время выполнения вы потеряли параметр и просто знали, что это Дом объект.

Java generics удаляет общий тип информации о компиляции. Вы не сможете получить эту информацию во время выполнения.