Hprose for Java类型映射
戴品
2023-12-01
类型映射是Hprose的基础,正是因为Hprose设计有良好的类型映射机制,才使得多语言互通得以实现。本章将对Hprose for Java的类型映射进行一个详细的介绍。
[b][size=x-large]基本类型[/size][/b]
[b][size=large]值类型[/size][/b]
[table]
|类型| 描述|
|整型| Hprose中的整型为32位有符号整型数,表示范围是-2147483648~2147483647(-231~231-1)。|
|长整型| Hprose中的长整型为有符号无限长整型数,表示范围仅跟内存容量有关。|
|浮点型| Hprose中的浮点型为双精度浮点型数。|
|非数| Hprose中的非数表示浮点型数中的非数(NaN)。|
|无穷大| Hprose中的无穷大表示浮点型数中的正负无穷大数。|
|布尔型| Hprose中的布尔型只有真假两个值。|
|空| Hprose中的空表示引用类型的值为空(null)。|
|空串| Hprose中的空串表示空字符串或零长度的二进制型。|
[/table]
其中非数和无穷大其实是特殊的浮点型数据,只不过在Hprose中它们有单独的表示方式,这样可以使它们占用更少的存储空间,并得到更快的解析。
另一个可能会引起您注意的是,这里把空和空串也作为值类型对待了。这里把它列为值类型而不是引用类型,是因为Hprose中的值类型和引用类型的概念与程序设计语言中的概念不完全相同。这里的值类型是表示在Hprose序列化过程中,不做引用计数的类型。在序列化过程中,当遇到相等的值类型时,后写入的值将与先写入的值保持相同的形式,而不是以引用的形式写入。
[b][size=large]引用类型[/size][/b]
[table]
|类型| 描述|
|二进制型| Hprose中的二进制型表示二进制数据,例如字节数组或二进制字符串。|
|字符串型| Hprose中的字符串型表示Unicode字符串数据,以标准UTF-8编码存储。|
|日期型| Hprose中的日期型表示年、月、日,年份范围是0~9999。|
|时间型| Hprose中的时间型表示时、分、秒(毫秒,微秒,毫微秒为可选部分)。|
|日期时间型| Hprose中的日期时间型表示某天的某个时刻,可表示本地或UTC时间。|
[/table]
空字符串和零长度的二进制型并不总是表示为空串类型,在某些情况下它们也表示为各自的引用类型。空串类型只是对二进制型和字符串型的特殊情况的一种优化表示。
引用类型在Hprose中有引用计数,在序列化过程中,当遇到相等的引用类型时,后写入的值是先前写入的值的引用编号。
后面介绍的容器类型和对象类型也都属于引用类型。
[b][size=large]基本类型的映射[/size][/b]
Java类型与Hprose类型的映射关系不是一一对应的。在序列化过程中可能会有多种Java类型对应同一种Hprose类型,在反序列化过程中还分为默认类型映射和有效类型映射,对于有效类型映射还分为安全类型映射和非安全类型映射两种。我们下面以列表的形式来说明。
[b]序列化类型映射[/b]
[table]
|Java类型| Hprose类型|
|byte, short, int, char, Byte, Short, Integer, Character, Enum| 整型|
|long, Long, BigInteger| 长整型|
|float, double, Float, Double| 浮点型|
|Float.NaN, Double.NaN| 非数|
|Float.POSITIVE_INFINITY, Double.POSITIVE_INFINITY| 正无穷大|
|Float.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY| 负无穷大|
|true, Boolean.TRUE| 布尔真|
|false, Boolean.FALSE| 布尔假|
|null| 空|
|byte[]| 二进制型(或空串)|
|char[], String, StringBuffer, BigDecimal| 字符串型(或空串)|
|java.sql.Date| 日期型|
|java.sql.Time| 时间型|
|java.util.Date, java.util.Calendar| 日期时间型|
[/table]
[b]反序列化默认类型映射[/b]
默认类型是指在对Hprose数据反序列化时,在不指定类型信息的情况下得到的反序列化结果类型。
[table]
|Hprose类型| Java类型|
|整型| Integer|
|长整型| BigInteger|
|浮点型| Double|
|非数| Double.NaN|
|正无穷大| Double.POSITIVE_INFINITY|
|负无穷大| Double.NEGATIVE_INFINITY|
|布尔真| Boolean.TRUE|
|布尔假| Boolean.FALSE|
|空| null|
|空串| ""|
|二进制型| byte[]|
|字符串型| String|
|日期型| java.util.Calendar|
|时间型| java.util.Calendar|
|日期时间型| java.util.Calendar|
[/table]
[b]反序列化有效类型映射[/b]
有效类型是指在对Hprose数据反序列化时,可以指定的反序列化结果类型。当指定的类型为安全类型时,反序列化总是可以得到结果。当指定的类型为非安全类型时,只有当数据符合一定条件时,反序列化才能得到结果,不符合条件的情况下,可能会得到丢失精度的结果或者抛出异常。当指定的类型为非有效类型时,反序列化时会抛出异常。
[table]
|Hprose类型| Java类型(安全)| Java类型(非安全)|
|整型| Integer, Long, Float, Double, BigInteger, BigDecimal, String, Character| Byte, Short, Boolean, Enum, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp|
|长整型| BigInteger, BigDecimal, String| Byte, Short, Integer, Long, Float, Double, Boolean, Enum, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, Character|
|浮点型| Double, BigDecimal, String| Byte, Short, Integer, Long, Float, BigInteger, Boolean, Enum, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, Character|
|非数| Float.NaN, Double.NaN, String| 无|
|正无穷大| Float.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, String| 无|
|负无穷大| Float.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, String| 无|
|布尔真| Boolean.TRUE, Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal, String, Character| 无|
|布尔假| Boolean.FALSE, Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal, String, Character| 无|
|空| 任意类型| 无|
|空串| byte[0], char[0], "", StringBuffer| 无|
|二进制型| byte[]| String|
|字符串型| String, StringBuffer, char[], byte[]| Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal, Character|
|日期型| java.util.Calendar, java.util.GregorianCalendar, java.util.Date, java.sql.Date, java.sql.Timestamp, Long| java.sql.Time|
|时间型| java.util.Calendar, java.util.GregorianCalendar, java.util.Date, java.sql.Time, java.sql.Timestamp, Long| java.sql.Date|
|日期时间型| java.util.Calendar, java.util.GregorianCalendar, java.util.Date, java.sql.Timestamp, Long| java.sql.Date, java.sql.Time|
[/table]
[b][size=x-large]容器类型[/size][/b]
Hprose中的容器类型包括列表类型和字典类型两种。下面我们来分别介绍它们与Java类型的映射关系。
[b][size=large]列表类型[/size][/b]
[b]序列化类型映射[/b]
除byte[],char[]以外的所有其它数组类型和所有实现了Collection接口的类型均映射为Hprose列表类型。
[b]反序列化类型映射[/b]
Hprose列表类型默认映射为Java的ArrayList类型。有效类型为:
[list]
[*]所有数组类型
[*]所有实现了Collection接口的可实例化类型
[/list]
[b][size=large]字典类型[/size][/b]
[b]序列化类型映射[/b]
所有实现了Map接口的类型均映射为Hprose字典类型。
[b]反序列化类型映射[/b]
Hprose字典类型默认映射为Java的HashMap类型。有效类型为:
[list]
[*]所有实现了Map接口的可实例化类型
[*]所有拥有与字典中Key所对应的属性或字段相同的自定义可序列化可实例化类型
[/list]
[b][size=x-large]对象类型[/size][/b]
Java中自定义的可序列化对象类型在序列化时被映射为Hprose对象类型。
Hprose对象类型在反序列化时被映射为:
[list]
[*]Java中自定义的可序列化对象类型
[*]HashMap(当上述类型定义不存在时)
[/list]
[color=red]注意:Hprose所支持的Java自定义可序列化对象类型仅是Java可序列化类型的一个子集。Hprose对Java对象类型的序列化分为两种,一种是按属性序列化,一种是按字段序列化。这两种方式下都需要在定义类时实现java.io.Serializable接口。按属性序列化时,只有get(is)和set存取方法都定义的属性会被序列化。按字段序列化时,没有标明transient的字段都会被序列化。[/color]