0

Unten habe ich das Beispiel eingefügt, das ich ausführen möchte.Java ClassCastException nimmt ParameterizedType E von generischer Instanz "neu ClazzXXX <E>()"

Ich kann leicht die generische Klasse einer StringHome Instanz, die Home<String> erweitert, aber ich kann nicht das gleiche mit einer new Home<String>() Instanz zu bekommen. Wie kann ich es erhalten?

Mein Ziel ist mainKO Methode funktioniert wie die mainOK tut.

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()); 
    } 
} 

Die Ausführung dieser Klasse druckt diese:

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

Sie können einfach nicht. –

+0

Können Sie mir erklären, warum das technisch nicht möglich ist? – madx

Antwort

2

können Sie nicht.

Um das zu verstehen, machen Sie einfach einen Baum von jeder Hierarchie Ihres Objekts.

  • StringHome ‚s Super ist Startseite <java.lang.String>. Wenn Sie also getGenericSuperclass() aufrufen, erhalten Sie diese Oberklasse. Dann können Sie den tatsächlichen Typparameter String erhalten.

ABER

  • Startseite <String> ‚s Super ist java.lang.Object. Außerdem haben Sie zur Laufzeit Parameter verloren und könnten einfach wissen, dass es ein Objekt ist.

Java-Generika löschen generische Typinformationen auf kompilieren. Sie können diese Informationen zur Laufzeit nicht abrufen.