2013-02-01 78 views
2

我最近開始重構我的Java代碼。這一切都運行良好,直到後來,我注意到我的一些對象丟失「正確的參考」,即它成爲的情況下,對象是「通過值」,而不是「通過引用」 。請注意,我確實知道Java始終是pass-by-value,並且僅通過內存地址傳遞來模擬傳遞引用(這就是爲什麼我引用這兩個短語的原因)。對象之間的區別o = makeMeAnObjectPlease();和Object o = new Object();

我的問題是:是否有

Object o = new Object(); 

Object o = makeMeAnObjectPlease(); 

其中

public Object makeMeAnObjectPlease() 
{ 
    Object c = new Object(); 
    return c; 
} 

而且通過差異,我的意思之間的差異將oObject o = makeMeAnObjectPlease()後指該與在makeMeAnObjectPlease()內創建的內存地址相同?還有更多的區別嗎?

+1

你可能想看看這個問題的答案:http://stackoverflow.com/questions/40480/is-java-pass-by-reference – Natix

回答

3

是的,它會引用同一個對象。不,沒有其他區別。進一步舉例:

Date d = makeMeAnObjectPlease(); 
System.out.println(d); 
Date d2 = d; 
changeMyObjectPlease(d2); 
System.out.println(d); 
System.out.println(d2); 

Date makeMeAnObjectPlease() { 
    return new Date(); 
} 

void changeMyObjectPlease(Date date) { 
    date.setTime(1234); 
} 

該代碼中只有一個Date對象,儘管它在不同時間被不同的名稱所知。最後,所有名稱都指向同一個對象,因此最終,當我們用兩個不同的名稱打印對象時,您會看到它們實際上指示了內存中的相同對象,該對象已由changeMyObjectPlease()方法修改。運行上面的例子是:

Thu Jan 31 19:29:29 CST 2013 
Wed Dec 31 18:00:01 CST 1969 
Wed Dec 31 18:00:01 CST 1969 
+0

我接受這個答案,因爲他的例子真的清除了它出。 :D – brain56

1

正如其他人說,你看它,就在all.The唯一的區別沒有差別來自於可能是什麼。

例如,如果您不知道/控制定義makeMeAnObjectPlease,它可以返回Object的任何子類,並且代碼仍然保留,而第1個選項將始終返回Object。對於這種抽象,第二種風格通常用於Factory Pattern

1

在o = makeMeAnObjectPlease()引用與makeMeAnObjectPlease()內創建的內存地址相同的內存地址後?

我們不談論Java中的內存地址。它會引用同一個對象。它怎麼會不?

還有更多的區別嗎?

只有額外的方法調用,以及其中的任何內容。

+1

「它怎麼會不?」通過C++風格的複製構造。 –

2

這兩種方法之間沒有功能差異。

在第一個示例中,創建了一個new Object,該對象的參考位置存儲在Object參考變量o中。

在第二個示例中,對於c發生相同的過程。然後將c(對創建對象的內存引用)的值複製到o中。如果co在這一點上都在範圍內,則通過o(通過調用方法或更改字段)完成的任何變異將反映在c中,反之亦然。

回答您有關Java引用是如何工作的,請考慮以下問題:

Object o,c; 
o = c = new Object(); 

在這個例子中,oc具有相同的值(一個參考的Object),並指向同一目的。我可以將o傳遞給方法,通過訪問c中的Object來改變它指向的對象並見證更改。但是,如果我給你一個新的對象到參考我傳遞(如以下)

public class Test{ 

    public static void main(String[] args){ 
     Object o,c; 
     o = c = new Object(); 
     assignIntoTheReferencePlease(c); 
     System.out.println(o == c); 
    } 

    public static void assignIntoTheReferencePlease(Object c){ 
     c = new Object(); 
    } 
} 

沒有任何反應(和程序打印true)。

爲什麼?

這是因爲你所說的是真實的 - 所有方法調用和返回值都是,值。這意味着將參考值c複製到方法變量c中。對該變量進行的任何分配都不會影響外部範圍中的其他變量,因爲它不是真正的指針。

我希望我能回答你的問題。

相關問題