我一直在研究Java中XML-RPC的实现。主要的开源库(例如Apache XML-RPC)使用原始类型来表示Java中的某些XML-RPC类型,例如,结构表示为原始地图。
在Java中不鼓励使用新代码中的原始类型。来自JLS,
原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型。未来版本的Java编程语言可能会禁止使用原始类型。
但是,由于XML-RPC protocol的性质,在这种情况下原始类型是不可避免的吗?
答案 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
可能是另一个List
或Map
- 在这种情况下甚至可以转换为List<Object>
或Map<String, Object>
分别会发出一系列unchecked cast
警告。
就实用性而言,就API处理或内省任意XML-RPC数据结构而言,是原始类型可能是不可避免的。或者不值得避免。 (在许多方面,鉴于编译时类型擦除,它对反射和序列化也是一个类似的挑战。)
现在,有一线希望是这些库有可能支持将这些非常通用的XML-RPC数据结构编组到特定应用程序定义的特定强类型类中。但是如果你有一个支持该路由的库,希望你不再需要直接处理struct / array表示。 (或者如果你是,希望你的数据模型不会在同一个“数组”中混合不同的值类型。)
我希望有所帮助。