我不太确定如何最好地解释这个问题,所以我写了同样的Java和Kotlin代码来更好地演示。
当我读取JSON时,它似乎强制将数据bean值设为NULL,即使该参数根本不是JSON的一部分,并且数据bean默认缺失字段的值。在Java中,它可以正确地工作,从未尝试将从未提供的值变为空值。但在Kotlin中,它似乎会出现问题,因为它试图使非空字段为空。
在Kotlin中
data class Pojo(val name: String, val age: Int, val list: List<String> = emptyList(), val ts: Date = Date())
private val mapper: ObjectMapper = ObjectMapper().registerModule(KotlinModule())
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
fun main(args: Array<String>) {
mapper.readValue("""{"name": "John Doe", "list": ["yellow", "green"], "age": 42}""", Pojo::class.java)
}
这会抛出一个异常:
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method Pojo.<init>, parameter ts
在Java中(一切都运作良好)
public class Transform {
private static ObjectMapper mapper = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
public static class Pojo {
private String name;
private int age;
private List<String> list;
private Date ts = new Date();
<getters and setters for all>
}
public static void main(String[] args) throws IOException {
String json = "{\"name\": \"John Doe\", \"list\": [\"yellow\", \"green\"], \"age\": 42}";
Pojo p = mapper.readValue(json, Pojo.class);
System.out.printf("Bean: name=%s, age=%s, list=%s, ts=%s\n", p.name, p.age, p.list, p.ts);
}
}
即使我在Kotlin中将其作为类而不是数据类,它仍然以同样的方式出错。
我的问题是,如何在Kotlin中使用我的POJO使Jackson反序列化工作。期望的行为是,如果传递了空/不正确的值,它“应该”中断。但在上述情况下,在根本没有尝试将ts字段更改为null的情况下,它应该像Java一样使用默认值。
唯一让我想到并且似乎起作用的事情是根本不使用数据bean的概念,并像这样编写我的bean:
class Pojo(val name: String, val age: Int) {
var list: List<String> = emptyList()
var ts: Date = Date()
}
但是,我的 .equals 方法不起作用,并且它允许下游用户操纵列表的内容和 ts 属性,而我希望这些属性只读。