0

以下に、実行したい例を貼り付けました。

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)
4

1 に答える 1

2

できません。

それを理解するには、オブジェクトの各階層のツリーを作成してください。

  • StringHomeのスーパークラスはHome<java.lang.String>です。したがって、getGenericSuperclass() を呼び出すと、そのスーパークラスが取得されます。次に、実際の型パラメーターStringを取得できます。

しかし

  • Home<String>のスーパークラスはjava.lang.Objectです。さらに、実行時にパラメーターが失われ、それがHomeオブジェクトであることがわかります。

Java ジェネリックは、コンパイル時にジェネリック型情報を消去します。実行時にこの情報を取得することはできません。

于 2016-07-01T15:15:11.603 に答える