2013-11-14 176 views
2

比方說,我有一個簡單的類人最佳實踐

public class Person{ 
    final List<String> names= Lists.newArrayList(); 

    public List<String> getNames(){ 
    return names; 
    } 
} 

如果我嘗試deserialise與傑克遜(2.2)

Person l = mapper.readValue(js,Person.class); 

我得到Disabling Afterburner deserialization ....due to access error (type java.lang.IllegalAccessError ....

這是因爲最終名稱名單。爲了解決這個問題,我設置了MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORSfalse

這是正確的解決方案還是更好的只是爲了使列表非最終?

是否有Jackson方法使用collection.add方法初始化集合?

或者也許有更好的辦法。這裏可以提出什麼建議?

編輯:我現在發現這個設置:

USE_GETTERS_AS_SETTERS(默認值:true)控制是否 返回集合或地圖類型可用於「設置」值(同一 如何JAXB「干將」 API與XML協同工作),因此單獨的「setter」方法不需要 。即使啓用,明確的「setter」方法將具有 優先於隱式getter-as-setter(如果存在)。

看起來像我正在尋找的東西,它默認情況下。那麼爲什麼忽略呢?

回答

2

在您的應用程序中使用不可變對象是最佳做法,但在外部世界(非Java)的邊界上,您通常不得不使用它們。

在大多數序列化技術中,當對象是「良好行爲」(可變的,根據JavaBeans標準的getter和setter)時,一切正常。通常有一些方法可以解決,但根據我的經驗,只要你不打算從其他Java代碼中引用它,就讓這個該死的東西變爲可變的是最容易的。 (如果最壞情況發生,最好創建一個專用序列化DTO)

+1

是的,我同意一般。但這具體是關於收集領域和傑克遜。爲了消除任何空收集字段的機會,我只是在初始化程序中創建它們並將它們設置爲最終。人們總是可以通過集合的添加方法向其添加元素。所以收集狀態是可變的,但不是它本身。我期待着有什麼方法可以讓傑克遜使用這些添加方法來初始化集合。 – husayt

1

我懷疑這是由於組合問題。具體來說,你可以嘗試你的方法,而不先啓用Afterburner?如果這可行,那麼這是Afterburner模塊處理處理的問題 - 這可能是因爲此處涉及的代碼路徑與默認路徑不同。 請務必使用最新版本; 2.3.0剛剛發佈。

+0

是的,它沒有加力燃燒室。但有了加力燃燒器,我也遇到了IllegalAccessError和最新版本。然後,我必須啓用ALLOW_FINAL_FIELDS_AS_MUTATORS才能與Afterburner一起工作,這很奇怪,因爲我不知道它的含義。這看起來像加力燃燒室中的一個錯誤。根據文件,它應該添加元素到收藏而不是改變它。 – husayt

+1

我會爲Afterburner提出一個錯誤;這很可能很容易解決。 – StaxMan

+0

謝謝@Staxman,已經報告了一個錯誤。我只是不確定這是否是預期的行爲。 – husayt