【问题标题】:Java reflection and generics - parameterized type info missing "extends"Java 反射和泛型 - 缺少“扩展”的参数化类型信息
【发布时间】:2016-02-05 21:17:04
【问题描述】:

我想在 Java 8 中使用反射重构方法的签名。我遇到了泛型方法的一些问题。 特别是,我找不到任何可以帮助恢复有关模板类型声明中“扩展”或“超级”情况的信息。

这是一个基于已知源代码的特定测试用例:

来自源代码的方法签名:
public static <T extends AssertDelegateTarget> T assertThat(T assertion)

首先,有没有一种优雅的方式来重构<T extends AssertDelegateTarget> 部分而无需解析字符串?

这是我通过反思获得的主要信息:

  • method.toString():

    public static org.assertj.core.api.AssertDelegateTarget org.assertj.core.api.Assertions.assertThat(org.assertj.core.api.AssertDelegateTarget)

  • method.toGenericString():

    public static <T> T org.assertj.core.api.Assertions.assertThat(T)

    “扩展 AssertDelegateTarget”发生了什么?

  • method.getReturnType.toString():

    interface org.assertj.core.api.AssertDelegateTarget

  • method.getGenericParameterTypes()[0].getTypeName():

    T

根据上述反射信息,我可以假设 T 和 AssertDelegateTarget 之间存在关系,但我如何知道它是“扩展”还是“超级”?

【问题讨论】:

    标签: java generics reflection


    【解决方案1】:

    您已经拥有Method 对象。从这里开始,用the getTypeParameters method获取方法上声明的类型参数,它返回一个TypeVariable<Method>[]。这是在方法上声明的类型参数的数组。在这种情况下,它只有一个类型参数,因此返回的数组只有一个元素。

    TypeVariable interface 具有检索名称 TgetName 的方法和检索边界的方法 getBoundsgetBounds 方法返回 Type[]。可以确定这里的任何边界都是上限,因为类型变量的声明不允许使用super,只能使用extends

    在这种情况下,Type 变量只是AssertDelegateTargetClass 对象。

    现在您可以根据上述信息重新构造"<T extends AssertDelegateTarget>" 字符串。仅当 Type[] 非空时才使用“扩展”。如果有多个界限,您可以在它们之间放置一个逗号,例如T extends Bound1, Bound2.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-24
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多