0

에서 가져 오는 중 아래 예제를 실행하려면 다음을 실행하십시오.Java ClassCastException 매개 변수가있는 유형 E를 일반 인스턴스 "new ClazzXXX <E>()"

Home<String>을 확장하는 StringHome 인스턴스의 일반 클래스를 쉽게 얻을 수 있지만 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의 슈퍼 <java.lang.String>입니다. 따라서 getGenericSuperclass()를 호출하면 해당 수퍼 클래스를 가져옵니다. 그런 다음 실제 유형 매개 변수 문자열을 얻을 수 있습니다.

하지만

  • <String>의 슈퍼 java.lang.Object 상위입니다. 또한 런타임에 매개 변수를 잃어서 개체라는 것을 알 수 있습니다.

Java 제네릭은 컴파일시 일반 유형 정보를 지 웁니다. 런타임에이 정보를 얻을 수 없습니다.