Object o = makeMeAnObjectPlease();和Object o = new Object();

时间:2013-02-01 01:19:43

标签: java oop object new-operator assignment-operator

我最近开始重构我的Java代码。它一直运行良好,直到后来,我注意到我的一些对象丢失了“正确引用”,即对象“按值传递”的情况 ,而不是“通过引用传递”。请注意,我确实理解Java始终是pass-by-value,并且通过引用传递仅通过内存地址传递进行模拟(这就是我引用这两个短语的原因)。

我的问题是:

之间有区别吗?
Object o = new Object();

Object o = makeMeAnObjectPlease();

,其中

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

通过差异,我的意思是oObject o = makeMeAnObjectPlease()引用与makeMeAnObjectPlease()内创建的内存地址相同的内存地址后会{{1}}吗?还有其他差异吗?

4 个答案:

答案 0 :(得分: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对象,尽管在不同的时间以不同的名称知道它。最后,所有名称都指向同一个对象,因此最后,当我们用两个不同的名称打印出对象时,你会看到它们实际上在内存中指示了同一个对象,它被{{ 1}}方法。运行上述内容的一个例子是:

changeMyObjectPlease()

答案 1 :(得分:2)

这两种方法之间没有功能差异。

在第一个示例中,创建了new Object,对象的参考位置存储在Object引用变量o中。

在第二个示例中,c发生了相同的过程。然后将c(对创建对象的内存引用)的值复制到o。如果此时co都在范围内,则o(通过调用方法或更改字段)所做的任何突变都将反映在c中,反之亦然。

要回答有关java中参考工作方式的问题,请考虑以下事项:

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

在此示例中,oc都具有相同的值(对Object的引用)并指向同一个对象。我可以将o传递给方法,通过访问Object中的c来改变它指向的对象并见证更改。但是,如果我将一个新对象分配给我传入的引用(如下所示)

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中。对该变量进行的任何赋值都不会影响外部作用域中的其他变量,因为它不是真正的指针。

我希望我回答你的问题。

答案 2 :(得分:1)

正如其他人所说,正如你所展示的那样,根本没有区别。唯一的区别在于它可能是什么。

例如,如果您不知道/控制定义makeMeAnObjectPlease,它可以返回Object的任何子类,代码仍将保留,而第一个选项将始终返回{{1} }。对于这种抽象,第二种风格通常用于Factory Pattern

答案 3 :(得分:1)

  

将在Object o = makeMeAnObjectPlease()后引用与makeMeAnObjectPlease()中创建的内存地址相同的内存地址?

我们不会谈论Java中的内存地址。它将引用相同的对象。怎么可能不是?

  

还有其他差异吗?

只有额外的方法调用,以及其中的任何内容。