我想在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之间存在关系,但是我如何知道它是“扩展”还是“超级”?

最佳答案

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

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

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

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

08-03 23:04