gpt4 book ai didi

java - DWR 如何转换传入数据并规避类型删除

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:40:32 26 4
gpt4 key购买 nike

我想申请一个项目类别的集合(具体反射(reflect))。但是关于类型删除似乎是不可能的,而且关于我在堆栈上阅读过的一些主题。有一些解决方法(here),但我很好奇是否有人知道它是如何完成的,例如 DWR:

http://directwebremoting.org/dwr/documentation/server/configuration/dwrxml/signatures.html

或者如果有更好的解决方法,那就太好了。

假设我们有这样的东西:

public String foo(List<String> possibleFoos) {

我需要做的就是找出参数 possibleFoos 是字符串列表,而不仅仅是列表

最佳答案

虽然 Java 确实会在运行时删除类型(从而将 List<String> 变成 List ),但在许多情况下,它实际上会在运行时存储泛型类型,从而允许您恢复因删除而丢失的信息。您可以检索这些的实际通用类型:

  • 方法参数(你的情况)
  • 方法返回类型
  • 字段类型
  • 父类(super class)/接口(interface)

这意味着如果您只有一个类型为 List 的对象,您将无法获得它的泛型类型(object.getClass() 将获得 List,仅此而已)- 它已永久丢失。但是,如果您试图找出方法参数或上述任何参数的泛型类型,您通常可以使用反射。由于您的案例不涉及类型变量或其他并发症,因此获取实际类型非常简单:

ParameterizedType listArgument = (ParameterizedType) ClassDeclaringFoo.class.getMethod("foo", List.class).getGenericParameterTypes()[0];
Type listType = listArgument.getActualTypeArguments()[0]; //This will be a Class representing String, the type of the List

如果您有更多参数和 map :

public String foo(Object bar, Map<String, Number> possibleFoos) { ... }

代码类似:

ParameterizedType mapArgument = (ParameterizedType) ClassDeclaringFoo.class.getMethod("foo", Object.class, Map.class).getGenericParameterTypes()[1]; //1 is the index of the map argument
Type keyType = mapArgument.getActualTypeArguments()[0]; //This will be a Class representing String, the type of the Map key
Type valType = mapArgument.getActualTypeArguments()[1]; //This will be a Class representing Number, the type of the Map value

可以安全地假设这也是 DWR 正在使用的,因为类型是方法参数。

其他列出的案例也有类似的方法:

  • Class.getMethod(...).getGenericReturnType()会给你真正的返回类型
  • Class.getField(fieldName).getGenericType()将为您提供该字段的真实类型
  • Class.getGenericSuperClass()会让你成为真正的 super 类型
  • Class.getGenericInterfaces()将为您提供真正的接口(interface)类型

存在允许访问 AnnotatedType 的等效方法Java 8 中引入的(泛型加上类型用法的注解):

  • Class.getMethod(...).getAnnotatedParameterTypes()
  • Class.getMethod(...).getAnnotatedReturnType()
  • Class.getField(fieldName).getAnnotatedType()
  • Class.getAnnotatedSuperClass()
  • Class.getAnnotatedInterfaces()

现在,当您的情况像示例中一样简单时,这一切都很好。但是,想象一下如果您的示例如下所示:

public T foo(List<T> possibleFoos) {...}

在这种情况下,getGenericParameterTypes()[0].getActualTypeArguments()[0]会给你T这是没用的。解决什么T代表,您必须查看类定义,也许还有父类(super class),同时跟踪类型变量在每个类中的命名方式,因为每个类中的名称可能不同。

为了更轻松地使用泛型类型反射,您可以使用一个名为 GenTyRef 的很棒的库这对你来说很辛苦,如果你需要支持 AnnotatedType s,你可以使用我的 fork GeAnTyRef (两者都在 Maven Central 中)。它们还包括一个类型工厂,允许您构造 (Annotated)Type 的实例。 ,使用普通的 Java API 无法轻松做到这一点。还有一个方便的 super type token实现允许您获得 (Annotated)Type字面意思。

有了这些,您就可以使用 Java 允许的泛型类型来完成所有事情,而无需我上面解释的麻烦:

  • GenericTypeReflector#getExactParameterTypes( ... )
  • GenericTypeReflector#getExactReturnType( ... )
  • GenericTypeReflector#getExactFieldType( ... )
  • GenericTypeReflector#getExactSuperType( ... )

还有更多的操作,比如判断一个 Type是另一个的父类(super class)型(类似于 Class#isAssignableFrom 但对于泛型类型),解析特定类型变量等。

关于java - DWR 如何转换传入数据并规避类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40038691/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com