只是:

public static class MyClass<T> {
    // i don't want to keep an instance of T, if it is not necessary.
    // and it is not nice, not neat.

    // Or, let's say, the member are in the form of :
    ArrayList<T> mArrayList = new ArrayList<T>();
    // the problem of getting the generic type parameter is still present.
}

@Test
public final void test() {
    MyClass<Integer> myObject = new MyClass<Integer>();
    getParamType( myObject );
}

private static final <T> void getParamType(final MyClass<T> _myObject) {
    System.out.println(_myObject.getClass().getTypeParameters()[0]);    // T
    System.out.println(((T) new Object()).getClass());                  // class java.lang.Object
}

如何让代码打印class java.lang.Integer

我知道很多stackoverflow线程正在询问(并回答)这个问题。但是他们无法解决这个问题。
  • 我不知道为什么有些人需要调用getGenericSuperclass()-因为在这种简单情况下不涉及继承。
  • 而且我也无法将其转换为ParameterizedType


  • System.out.println((ParameterizedType) _myObject.getClass());
    // Compile Error: Cannot cast from Class<capture#11-of ? extends TreeTest2.MyClass> to ParameterizedType
    
    System.out.println((ParameterizedType) _myObject.getClass().getGenericSuperclass());
    // Runtime Exception: java.lang.ClassCastException
    

    根据@Thomas的指南,我找到了一种解决方法来获取class java.lang.Integer

    首先,我们在测试代码中创建MyClass<T>的匿名(需要匿名)子类。 (这很奇怪。为什么它仅支持子类?)
    @Test
    public final void test() {
        MyClass<Integer> myObject = new MyClass<Integer>() {};  // Anonymous sub-class
        getParamType( myObject );
    }
    

    然后,我们可以使用getGenericSuperclass()方法获取Type,然后将其转换为ParameterizedType,然后再使用getActualTypeArguments():
    private static final <T> void getParamType(final MyClass<T> _myObject) {
        System.out.println( ((ParameterizedType) _myObject.getClass().getGenericSuperclass()).getActualTypeArguments()[0] );
    }
    

    它完美地打印了class java.lang.Integer

    这是不太好,因为测试代码应该模拟实际情况,在这种情况下,用户很可能不会继续创建无意义的子类。

    此方法基于the TypeReference class的思想。但是我真的不知道如何使用它。我已经尝试过class MyClass<T> extends TypeReference<T>。但是我仍然必须创建MyClass<T>的子类,以使TypeReference.getType()打印class java.lang.Integer

    请帮助,并感谢您的任何投入,因为最好的方法尚不存在。

    基于上述解决方法的另一个问题:为什么只有匿名子类起作用?
    public static class SubMyClass<T> extends MyClass<T>{}
    
    @Test
    public final void test() {
        MyClass<Integer> myObject = new MyClass<Integer>() {};  // Anonymous sub-class
        getParamType( myObject );               // class java.lang.Integer
    
        MyClass<Integer> mySubObject = new SubMyClass<Integer>();   // named sub-class
        getParamType( mySubObject );            // T
    }
    

    (MyClassgetParamType()不变。)

    最佳答案

    这有点困难,因为Java故意无法做到这一点(“类型擦除”)。

    解决方法称为super type tokens。 SO上也有一些关于此的线程(例如this onethat one)。

    10-01 02:49
    查看更多