有點挖後,原因就很清楚了。我產生了一些代碼xjc
和一個列表屬性,它創造了這個評論:
/**
* Gets the value of the bars property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the bars property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getBars().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link Bar }
*
*
*/
這使得他們的意圖明確。他們希望從對象中得到陳舊的List
是不可能的,所以它總是返回實時列表而不是複製。這意味着多次調用getter(例如,從不同的線程或不同的上下文),將始終被引用相同的內存中對象。但是,這樣做意味着他們不能擁有二傳手,否則他們會違反合同 - 上下文A可以設置價值,上下文B對舊價值有過時的參考,並且無法知道它已經改變了。
由於,因爲設計決定的,他們不能有一個二傳手,有需要有某種方式發生變異,如果你需要添加或刪除項目列表。否則,一個最初的null
列表永遠是null
永遠(禁止shenanigans反思)。因此,剩下的唯一方法是在getter中檢查null
,並在當時進行延遲初始化。這意味着更換整個列表中的方案必須是
foo.getBars().clear();
foo.getBars().addAll(someList);
至於爲什麼他們選擇了這樣的設計...有沒有辦法讓那支球隊之外任何人都知道這個問題的答案。然而,無論如何,對大多數代碼來說,它通常是一個非常好的模式(它減少了耦合,並消除了編譯器無法警告你的常見錯誤條件),所以很難對它做出反駁。如果它確實給你帶來了麻煩(而且你還沒有真正展示過它是如何的,除了一些對象在複製操作之後有空列表而不是空的列表),那麼我可以給你的唯一建議是要麼不使用代碼生成器,要麼寫一個xjc
的擴展名,以使其按照自己的意願進行操作。這可能甚至有一個現有的擴展。我不知道。
「我要求在某些情況下,這不是一件好事」介意解釋這一點? –
@Josh M,例如現在我使用Dozer合併相同類型的對象。源對象具有空列表,但在調用getters列表後進行初始化。所以源對象具有空列表,因此目標對象具有空列表。我有複雜的結構,我不想初始化空列表。源對象已更改,不應更改。由於沒有辦法改變這種產生getter的方式,我認爲有這樣一個產生getter的真正好理由。回到我的問題:這是什麼原因? – Hubert
我認爲這是一個非常愚蠢的問題,因爲我得到了低估。看起來只有我不知道爲什麼發電機這樣工作。尼斯。 – Hubert