java - 将未知对象转换为适当的 Method.invoke 参数的有效方法?

标签 java reflection

我正在编写一个基于反射的 RPC 服务,该服务通过各种机制获取传入的参数。有时参数与参数类型正确匹配,有时它们始终是字符串,有时它们包装在动态类型的“脚本”对象中,需要提取适当的值。

在调用 method.invoke 之前,我需要构建参数列表,如下所示:

Object a[] = new Object[method.parameterClasses.length];
for (int i = 0; i < a.length; ++i)
{
   a[i] = prepare(method.parameterClasses[i], rpc.arguments[i]);
}

“准备”方法看起来像:

Object prepare(Class clazz, Object o)
{
   if (o == null) return null;
   if (clazz == o.getClass()) return o;
   if (clazz == String.class) return o.toString();

   // skip a bunch of stuff for converting strings to dates and whatnot

   // skip a bunch of stuff for converting dynamic types

   // final attempts:
   try
   {
       return clazz.cast(o);
   }
   catch (Exception e)
   {
       return o;     // I give up.  Try the invoke and hope for the best!
   }


}

在单元测试期间,我最近相当惊讶地发现,一个传递一个盒装整数的方法,该整数期望一个原始的 long,实际上是失败的转换并跌入底部,然后在调用()期间被某些东西正确转换。我以为调用“cast”就能解决问题。有什么方法可以显式执行和检查调用通常完成的参数转换吗?

缺少这一点,我考虑对数字类型进行显式检查,但排列的数量似乎无法控制。当我添加对从脚本动态类型中提取数字并转换字符串的支持时,情况会变得更糟。我设想对每个可能的数字目标类进行一堆条件类型检查,对字符串参数使用 Integer.decode、Long.decode 等,对数字使用 Short.decode 和 Number.intValue、Number.longValue 等。

有没有更好的方法来完成这一切?起初这似乎是一个不错的方法,但它变得非常令人讨厌。

最佳答案

这确实令人惊讶,但这就是当前的行为。请参阅错误 6456930

就解决问题的更好方法而言,从本质上讲,您必须定义所有这些规则。不过,还有比一系列 if 更好(更易于维护)的模式。对于初学者来说,我有一些策略对象,可以为这些对象的一侧(可能是类一侧)调用,以便您根据类查找适当的对象(例如从 Map 中),然后您可以限制您向一侧的转换(每个对象都会关心如何将事物放入该特定类中)。这样,当您需要支持一种新的类转换时,您可以为其编写一个对象,单独测试它,然后将其插入映射中,而无需更改更多代码。

关于java - 将未知对象转换为适当的 Method.invoke 参数的有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1494425/

相关文章:

java转换库可以处理泛型类型吗?

function - 如何在 golang 中记录函数调用返回值

javascript - 如何在 Javascript 中访问函数的 return 语句

java - CSV 文件生成

java - 当我们到达 Horizo​​ntalScrollView 中的最后一项时指示器消失

java - 如何使用 Java 反射调用抛出异常的方法?

java - 在我的应用程序中查找所有 Jersey 资源方法的列表?

java - 使用 OpenJDK 1.8 的 JavaFX 的 Maven 依赖项

java - RequestMapping 占位符在 JUnit 测试中不起作用

java - Google App 引擎外部数据库