2013-02-01 62 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中。对该变量进行的任何分配都不会影响外部范围中的其他变量,因为它不是真正的指针。

我希望我能回答你的问题。

相关问题