2013-05-15 73 views
3

我對Java中的對象引用有疑問。它總是通過引用函數來發送它的對象,這意味着如果你在發送的函數中修改它們,它們會回來修改。Java中的引用對象

解決方法是在發送前複製對象。但爲此,我必須在對象類中創建一個複製函數嗎?還是有其他的選擇嗎?謝謝

+7

_It始終通過引用函數_發送它的對象_否,它發送參考值的副本。 –

+0

有沒有簡單的解決方案。看看java中不可變對象的解釋:http://www.javapractices.com/topic/TopicAction.do?Id=29 如果你希望你的對象是不可變的,你必須自己編寫行爲。 – NeplatnyUdaj

+0

有一個原因,對象是通過引用傳遞的,你的代碼不應該試圖修改這個行爲,而是將它用於你的優勢。你有沒有需要發送對象副本的代碼示例? – BLuFeNiX

回答

3

我通常會添加一個拷貝構造函數爲這種情況的,像這樣:

public class MyObject { 
    //members 


    public MyObject(MyObject objectToCopy) { 
     this.member = objectToCopy.member; 
     //... 
    } 
} 

然後,你可以用一個簡單的襯墊製作一個新的物體。

public void DoWork(MyObject object) { 
    MyObject copy = new MyObject(object); 
    //do stuff 
} 
+1

是不是最好的實踐是實現克隆? – danieln

+1

-1:很抱歉說,但這是複製/克隆對象的錯誤方法。更多信息:[Java:深層克隆/複製實例的推薦解決方案](http://stackoverflow.com/q/2156120/1065197) –

+0

對於更復雜的對象,這會導致非常混亂的代碼。我不會建議像這樣複製。 – Vegard

1

你應該爲每個對象自己創建一個拷貝構造函數。原因很簡單:如果A引用B並且您想要複製A,那麼您是否將引用複製到B或整個引用的B對象?這個問題必須單獨回答每個案例,所以沒有通用的解決方案。

1

確實發送了對象,並且將對引用的對象進行更改。有沒有簡單的「原生」的方式在Java中複製的對象,但你可以通過使用框架,如推土機複製對象:

http://dozer.sourceforge.net/

3

Java總是按價值傳遞。你所描述的是按值傳遞對象引用。

這裏有一個關鍵的區別。您沒有將該對象作爲參考傳遞,因此參考鏈接被打破as soon as you assign a new instance to your parameter。只要參考值保持不變,當您返回給調用者時,更改傳入的對象的內容將保持不變。另一個關鍵的區別是參考值可以是null ...但是null不是一個對象 - 那麼如何引用缺少對象?

如果你想創建一個新的對象,你需要複製現有的對象。副本應在方法內部執行以確保操作一致。

對於簡單的對象(帶着淺淺的類層次的對象,如下面的例子),通常可以用基本的拷貝構造函數獲得通過:

class Album { 
    private String title; 
    private String artist; 

    public Album(Album copy) { 
    this.title = copy.title; 
    this.artist = copy.artist; 
    } 
} 

這將允許您將對象複製你的方法內:

public void copyAlbum(Album album) { 
    album = new Album(album); // Clone the album passed in 
} 

對於更復雜的對象圖,你可能要使用這樣的庫爲OrikaDozer準確地創建對象的深副本。 This question在Java中複製對象有一些有用的建議。

+0

第一句話+1。 – Gamb

+1

你的回答很好,直到你寫了那個例子克隆對象... –

+0

請定義* simple *類(不是對象,因爲對象是類的一個實例)。 –