序列化器如何知道什么时候必须考虑一个类"原始"?

时间:2016-04-13 17:29:50

标签: java serialization reflection

让我们以jackson serializer为例,说我们有这样一个类:

public class Car {
    private String brand;
    private Integer weight;
}

如果我们将其序列化,我们将获得例如:

{
    "brand": "Fiat",        
    "weight": 50
}

但是它怎么知道String不是由不同原始值组成的对象?我的意思是它里面有属性,Integer类也是如此。 那为什么不像这样序列化呢?

{
    "brand": {
        "value": [  // primitive char[] inside String
            "F",
            "i",
            "a",
            "t",
        ],
        "hash": xxx // primitive int inside String
    }       
    "weight": {
        "value": 50 // primitive int inside Integer
    }
}

2 个答案:

答案 0 :(得分:2)

简单来说,您可以将这样的逻辑作为进行序列化的库的核心:

public String serializeValue(Object ob) {
    if (ob == null) {
       return NULL_REPRESENTATION;
    } else if (ob.getClass() == String.class) {
       return ob.toString();
    } else if (ob.getClass() == Integer.class) {
       return ob.toString();
    } else if (ob instanceof List) {
       return serializeArray( ((List)ob).toArray());
    } ...
    else {
       return serializeFieldsWithReflection(ob);
    }
}

实际上你永远不会完全看到它,因为这是组织代码的一种非常糟糕的方式,我只是用这种方式来编写它来展示基本思想。

相反,会有一堆可插入的序列化程序:每个特殊情况下,一个库提供自定义序列化(字符串,数字,日期,列表,地图,枚举),以及一个"泛型"序列化器,只迭代所有(非瞬态)字段。

此机制通常还允许您为自定义类插入自己的特殊序列化程序。

答案 1 :(得分:0)

jackson-databind模块为每个序列化对象的属性构造BeanPropertyWriter实例。如果它的底层JavaType不代表一个原语 - 可以使用toString()轻松序列化,它将属性序列化为对象,数组,映射或任何可行的。

查看扩展 com.fasterxml.jackson.databind.ser.std.StdSerializer

的类