Java XML-RPC和原始类型

时间:2013-11-26 21:39:39

标签: java generics xml-rpc

我一直在研究Java中XML-RPC的实现。主要的开源库(例如Apache XML-RPC)使用原始类型来表示Java中的某些XML-RPC类型,例如,结构表示为原始地图。

在Java中不鼓励使用新代码中的原始类型。来自JLS,

  

原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型。未来版本的Java编程语言可能会禁止使用原始类型。

但是,由于XML-RPC protocol的性质,在这种情况下原始类型是不可避免的吗?

1 个答案:

答案 0 :(得分:1)

给出Structs的XML-RPC示例:

<struct>
  <member>
    <name>submitter</name>
    <value><string>Deep Thought</string></value>
  </member>
  <member>
    <name>answer</name>
    <value><i4>42</i4></value>
  </member>
</struct>

...和数组:

<array>
  <data>
    <value><string>Don't Panic</string></value>
    <value><boolean>0</boolean></value>
    <value><dateTime.iso8601>19791012T12:24:42</dateTime.iso8601></value>
  </data>
</array>

根据规范,您可以看到他们可以混合同一结构中的数据类型。这是泛化通常旨在避免的事情。由于XML-RPC支持的数据类型广泛,唯一与所有这些类型兼容的常见超类最终是可靠的旧的java.lang.Object - 与原始集合相同的类型。

我认为从技术上讲,问题的答案是:没有,原始类型并非完全不可避免。但是,由于java.lang.Object是最大的共同点,因此更改Java5之前的API可能几乎没有实际优势,因为原始集合类型可以为您提供Object

为了论证,让我们看看无论如何可以做些什么来介绍泛型。首先,它几乎肯定是一个破坏API的变化(不是二进制API兼容),代码使用了以前版本的库(例如Apache的实现)。

接下来,在这种情况下,结构将从原始Map更改为使用泛型的最佳效果:Map<String, Object>。马上,您不再需要将密钥转换为String,以便以某种方式确定您是否关心相关值。但是,基于程序逻辑,在大多数非平凡的情况下,这个值仍然需要一些投射。

与结构类似,XML-RPC阵列可以从原始List切换到List<Object>,但这对程序逻辑没有任何影响。没有额外的元数据(比如struct的String字段名称)可以使这一点变得有利。

更糟糕的是,这两种数据结构都可以互相嵌套。因此,您从其中一个地图值(或数组/列表元素)获得的Object可能是另一个ListMap - 在这种情况下甚至可以转换为List<Object>Map<String, Object>分别会发出一系列unchecked cast警告。

实用性而言,就API处理或内省任意XML-RPC数据结构而言,原始类型可能是不可避免的。或者不值得避免。 (在许多方面,鉴于编译时类型擦除,它对反射和序列化也是一个类似的挑战。)

现在,有一线希望是这些库有可能支持将这些非常通用的XML-RPC数据结构编组到特定应用程序定义的特定强类型类中。但是如果你有一个支持该路由的库,希望你不再需要直接处理struct / array表示。 (或者如果你是,希望你的数据模型不会在同一个“数组”中混合不同的值类型。)

我希望有所帮助。