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