在通用上下文中使用getActualTypeArguments

安迪·巴兰(Andy Balaam):

还有例如,其他相关问题662411334039094516891但我的问题是更简单,更具体。

我想在运行时知道我的类使用什么类型的参数-我想要类型参数类型的Class对象。由于类型擦除,该表达式T.class不起作用,并且没有typeof(T)C#中的函数来获取它。

但是,可以通过ParameterizedType和相关类提供一些“超级反射” ,这几乎使我了解所有情况。

import java.lang.reflect.ParameterizedType;

public class MyClass<T> {
    public static void main( String[] args ) {
        new MyClass<Integer>().printTypeParam();
    }

    public void printTypeParam() {
        class DummyT extends MyClass<T> {}
        class DummyString extends MyClass<String> {}

        ParameterizedType ptT =
            ((ParameterizedType) DummyT.class.getGenericSuperclass() );

        ParameterizedType ptString =
            ((ParameterizedType) DummyString.class.getGenericSuperclass() );

        System.out.println( "DummyT: " + ptT + " " + ptT.getActualTypeArguments()[0] );
        System.out.println( "DummyString: " + ptString + " " + ptString.getActualTypeArguments()[0] );

    }
}

当我运行上面的代码时,我看到以下输出:

DummyT: MyClass<T> T
DummyString: MyClass<java.lang.String> class java.lang.String

如您所见,这适用于在编译时在包含对的调用的代码行getGenericSuperClass中知道类型实参的情况,但是在该调用本身处理泛型的地方,它仅打印类型参数的名称。

有什么办法可以java.lang.Integer代替第一行打印T

马克·彼得斯:

不能简单明了。Integer没有被具体化,它被完全擦除了如果您不相信我,请使用编译一次,Integer然后使用编译一次Long这两个二进制类文件将完全相同。

类型擦除是一个严酷的现实,您将无法解决。我建议您重新考虑为什么需要它,而不要像引入骇客一样尝试避免它。

有用的AngelikaLanger泛型常见问题解答主题:

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章