這對傑克遜數據綁定2.7.0仍然適用。
傑克遜@JsonCreator
annotation 2.5 javadoc或Jackson annotations documentation語法(構造小號和工廠方法小號)讓認爲確實是一個可以馬克多個構造。
標記註釋,可用於將構造函數和工廠方法定義爲用於實例化關聯類的新實例的標記註釋。
望着在創被識別的代碼,它看起來像傑克遜CreatorCollector
無視重載構造,因爲它只checks the first argument of the constructor。
Class<?> oldType = oldOne.getRawParameterType(0);
Class<?> newType = newOne.getRawParameterType(0);
if (oldType == newType) {
throw new IllegalArgumentException("Conflicting "+TYPE_DESCS[typeIndex]
+" creators: already had explicitly marked "+oldOne+", encountered "+newOne);
}
oldOne
是第一識別構造的創造者。
newOne
是重載構造函數的創建者。
這意味着,代碼類似將無法正常工作
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
this.country = "";
}
@JsonCreator
public Phone(@JsonProperty("country") String country, @JsonProperty("value") String value) {
this.value = value;
this.country = country;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336"); // raise error here
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
但這個代碼將工作:
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
這是一個有點哈克,可能不是面向未來。
該文檔對於如何創建對象是模糊的;從我從代碼集,雖然,那就是它可以混合不同的方法:
例如人們可以有註釋與@JsonCreator
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
@JsonCreator
public static Phone toPhone(String value) {
return new Phone(value);
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
它的工作原理,但它不是理想的靜態工廠方法。最後它可能是有意義的,例如如果json是dynamic那麼也許應該看看使用委託構造函數來處理負載變化比使用多註釋構造函數更優雅。
還要注意的是傑克遜orders creators by priority,例如在此代碼:
// Simple
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
}
// more
@JsonCreator
public Phone(Map<String, Object> properties) {
value = (String) properties.get("value");
// more logic
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
這次傑克遜不會引發錯誤,但傑克遜將只使用委託構造Phone(Map<String, Object> properties)
,這意味着Phone(@JsonProperty("value") String value)
是沒用過。
正如答案所指出的,不,您必須指定一個且唯一的構造函數。在你的情況下,離開那個需要多個參數的那個,這將工作得很好。 「Missing」參數將採用null(對象)或默認值(對於基元)。 – StaxMan 2013-04-10 21:24:56
謝謝。允許多個構造函數將是一個很好的功能。實際上,我的例子有點做作。我試圖使用的對象實際上有完全不同的參數列表,一個是正常創建的,另一個是使用Throwable創建的...我會看看我能做什麼,也許有一個空構造函數和getter/setter可以扔 – geejay 2013-04-11 07:25:39
是的,我確定它會很好,但是規則可以變得相當複雜,具有不同的排列方式。始終可以爲RFE提交新功能和特性。 – StaxMan 2013-04-15 23:12:58