bantouyan-json库是用来解析与编码Json数据的Java库,该库按照Json标准RFC4627编写,能够实现字符串与Json实例的相互转换,可以读取Reader得到Json实例,或将Json实例写入到Writer,还能将Collection与Map对象转换为Json实例。
RFC4627定义了Json的六种类型,分别是Array、Object、String、Number、Boolean(常量true与false)与Null(常量null)。在bantouyan-json库中,这些类型有枚举类型JsonType定义,其中Number被拆分为Integer与Float,非别表示整数与浮点数。这些类型的对应关系如下表所示:
RFC类型 | JsonType | Class | 实际存储类型 | 注释 |
Array | ARRAY | JsonArray | ArrayList | |
Object | OBJECT | JsonObject | HashMap | |
String | STRING | JsonPrimitive | java.lang.String | |
Number | INTEGER | JsonPrimitive | java.lang.Long | |
Number | FLOAT | JsonPrimitive | java.lang.Double | 不包括Infinity与NaN |
Boolean | BOOLEAN | JsonPrimitive | java.lang.Boolean | 对应常量true与false |
Null | NULL | JsonPrimitive | java.lang.String | 对应常量null |
INTEGER使用类型long存储整数,FLOAT使用类型double存储浮点数,但是,Java浮点数常量正负INFINITY与NaN存储为STRING类型,因为按照RFC4627这三个常量的字面量不符合Number的定义。
在bantouyan-json库中,JsonArray、JsonObject与JsonPrimitive有一个共同的超类Json,Json是一个抽象类,定义了这些类的一些共同特征,如Type、子元素的个数等,还提供了一些静态方法用来生成Json实例。
在解析、处理、编码Json的过程中,总会发生这样或那样的错误,为此,定义了JsonException异常。如果在处理Json实例过程中产生了异常,如存取类型不正确,Json实例内出现了循环引用等,或在解析String、Reader或Java Map、 Collection为Json实例过程中产生了错误,都会抛出JsonException异常。JsonException异常都属于RuntimeException,不必要时可以不予捕获。
在解析Collection或Map为Json实例的过程中,如果遇到普通的Java Class,bantouyan-json库就无法确定该如何解析这些普通类的对象。为此,json库中又定义了一个名为Jsonable的接口,该接口只有一个返回Json实例的方法generateJson()。故当解析Collection或Map时,如果遇到Jsonable的实例,就会调用所继承的generateJson()方法生成Json实例。
除了接口Jsonable外,bantouyan-json库还定义了另外一个接口JsonParser,也用于将Collection或Map的转换。与Jsonable只负责把自己转换为Json实例不同,JsonParser负责把其他的Java对象转换为Json实例。当我们需要把非自己编写的Java类转换为Json实例时,JsonParser非常有用。
特别警告:Json实例内部不允许出现循环引用,即Json实例内部,任何一个元素(包括顶层实例),都不能被其子元素或子元素的子元素引用,否则会引起一些方法出现异常或错误。因为从现实意义上讲,Json内部不会出现循环引用,但编写代码时可能有意无意的制造出有循环引用的实例。
相关阅读: