如何获得通用类型参数?

编程入门 行业动态 更新时间:2024-10-20 03:37:33
本文介绍了如何获得通用类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

简单地说:

public static class MyClass< T> { //如果没有必要,我不想保留T的一个实例。 //它不好,不整齐。 //或者,假设成员的形式如下: ArrayList< T> mArrayList = new ArrayList< T>(); //获取泛型类型参数的问题仍然存在。 } @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)new Object())。getClass()); // T System.out.println // class java.lang.Object }

如何让代码打印类java.lang.Integer ?

我知道很多stackoverflow线程正在询问(和回答)这个问题。但是他们无法解决这个问题。

  • 我不知道为什么有些人需要调用 getGenericSuperclass() - 因为在这个简单情况下没有继承。
  • 我不能将它转换为 ParameterizedType $ b $ p $
  • $ c> System.out.println((ParameterizedType)_myObject.getClass()); //编译错误:无法从Class< capture#11-of?扩展TreeTest2.MyClass> to ParameterizedType System.out.println((ParameterizedType)_myObject.getClass()。getGenericSuperclass()); //运行时异常:java.lang.ClassCastException

    基于@ Thomas的指导,我发现了一种 解决方法 来获取类java.lang.Integer ; T> 在测试代码中。 (这很奇怪,为什么它只支持子类?)

    @Test public final void test() { MyClass< Integer> myObject = new MyClass< Integer>(){}; //匿名子类 getParamType(myObject); $ / code>

    然后我们可以使用 getGenericSuperclass() code>方法来获取类型然后将其转换为 ParameterizedType ,之后使用 getActualTypeArguments():

    private static final< T> void getParamType(final MyClass< T> _myObject){ System.out.println(((ParameterizedType)_myObject.getClass()。getGenericSuperclass())。getActualTypeArguments()[0]); }

    完美地打印类java.lang.Integer 。

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

    这种方法基于 TypeReference类。但我真的不知道如何使用它。我试过 class MyClass< T>扩展了TypeReference< T> 。但我仍然需要创建 MyClass< T> 的子类以使 TypeReference.getType()打印 class java.lang.Integer 。

    请帮忙,谢谢任何输入,因为最好的方法还没有出现。 基于上述解决方法的进一步问题:为什么只有匿名子类有效?

    public static class SubMyClass< T>扩展MyClass< T> {} @Test public final void test(){ MyClass< Integer> myObject = new MyClass< Integer>(){}; //匿名子类 getParamType(myObject); // class java.lang.Integer MyClass< Integer> mySubObject = new SubMyClass< Integer>(); //命名的子类 getParamType(mySubObject); // T

    ( MyClass 和 getParamType()不变。)

    解决方案

    因为Java故意无法做到这一点(类型擦除)。

    解决方法称为超级类型令牌。还有一些关于此的线索(如这一个或那一个)。

    Simply:

    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 }

    How to let the code print class java.lang.Integer?

    i know quite a few of stackoverflow threads are asking (and answering) about this. Yet they couldn't solve this question.

    • i don't know why some need to call getGenericSuperclass() - as there is no inheritance involved in this simple case.
    • And i can't cast it to ParameterizedType as well.

    .

    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

    Based on @Thomas's guide, i have found a work-around way to get class java.lang.Integer.

    First, we create an anonymous (it need to be anonymous) sub-class of MyClass<T> in the testing code. (Which is weird. Why it only support sub-classes?)

    @Test public final void test() { MyClass<Integer> myObject = new MyClass<Integer>() {}; // Anonymous sub-class getParamType( myObject ); }

    Then we can use the getGenericSuperclass() method to get a Type then cast it to ParameterizedType and afterwards uses getActualTypeArguments():

    private static final <T> void getParamType(final MyClass<T> _myObject) { System.out.println( ((ParameterizedType) _myObject.getClass().getGenericSuperclass()).getActualTypeArguments()[0] ); }

    It perfectly prints class java.lang.Integer.

    This is not-so-good because the testing codes should simulate the actual situation, where users most likely won't keep creating meaningless sub-classes.

    This approach is based on the idea of the TypeReference class. But i don't really know how to use it. I have tried class MyClass<T> extends TypeReference<T>. But i still have to create sub-class of MyClass<T> to have TypeReference.getType() prints class java.lang.Integer.

    Please help, and thanks for any inputs, as the best approach is not here yet.

    A further question based on the above workaround: Why only anonymous sub-class works?

    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 }

    (MyClass and getParamType() unchanged.)

    解决方案

    This is sort of difficult, because Java deliberately can't do that ("type erasure").

    The work-around is called super type tokens. There are also some threads on SO about that (like this one or that one).

更多推荐

如何获得通用类型参数?

本文发布于:2023-11-11 23:18:56,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何获得   参数   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!