2014-02-18 58 views
-1

我不知道爲什麼(從XSD)生成getter方法列表始終空檢查:wsimport(xjc) - 爲什麼列表getter始終爲空檢查?

public class Response { 

    @XmlElement(type = Integer.class) 
    protected List<Integer> integers; 

    public List<Integer> getIntegers() { 
     if (integers == null) { 
      integers = new ArrayList<Integer>(); 
     } 
     return this.integers; 
    } 
} 

問:

爲什麼?是什麼原因?有沒有好的?

我問becouse在某些情況下,這是不是一件好事。看起來像沒有辦法改變這種行爲。

+0

「我要求在某些情況下,這不是一件好事」介意解釋這一點? –

+0

@Josh M,例如現在我使用Dozer合併相同類型的對象。源對象具有空列表,但在調用getters列表後進行初始化。所以源對象具有空列表,因此目標對象具有空列表。我有複雜的結構,我不想初始化空列表。源對象已更改,不應更改。由於沒有辦法改變這種產生getter的方式,我認爲有這樣一個產生getter的真正好理由。回到我的問題:這是什麼原因? – Hubert

+0

我認爲這是一個非常愚蠢的問題,因爲我得到了低估。看起來只有我不知道爲什麼發電機這樣工作。尼斯。 – Hubert

回答

4

有點挖後,原因就很清楚了。我產生了一些代碼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的擴展名,以使其按照自己的意願進行操作。這可能甚至有一個現有的擴展。我不知道。

+0

這是一個很好的答案,所以我認爲它可以被接受。謝謝你的努力。祝你今天愉快。 – Hubert