这段代码中创建了多少个对象? 以下是代码片段:

3
这段代码会创建多少个对象?
class Main {
  int num;
  public static void gacemarks(Main m)
  {
    m.num += 10;
  }
  public static void main(String[] args) {
    Main m1 = new Main();
    Main m2 = m1;
    Main m3 = new Main();
    m2.num = 60;
    gacemarks(m2);
    System.out.println(m2);
  }
}

答案是2。 但我得到了3。 m1将被创建,m2引用相同的对象。 m3是新创建的,在调用之后,生成了m对象。

我知道这是一个重复的问题。但是我无法理解这段代码。 - Nemaly Praveen
2
你混淆了对象引用(m1、m2、m3、m)和它们所引用的对象。只有在调用new语句(或 clone() 方法,但那是另一回事)时才会创建对象。 - RealSkeptic
m1m2是指同一个Main对象。m3是另一个Main对象。总共有两个 Main对象。 - khelwood
gacemarks(m2) 后尝试使用 System.out.println(m2.num)。你应该会得到70,因为 m 是指向 m2 所引用的对象的引用。 (我假设 System.out.println(m2) 没有显示出来,因为你没有重写 toString())。 - Thomas
它确实返回了十六进制代码!!! @Thomas - Nemaly Praveen
是的,这就是我想的,因为你没有覆盖 toString() 方法。 - Thomas
3个回答

3
在您的代码环境中,我只看到明确创建的两个对象,就是出现了new运算符的行中的内容:
Main m1 = new Main();
Main m3 = new Main();

以下是每行代码的具体解释:

这里给出了每行代码所代表的含义:

Main m1 = new Main();     // create new Main object 'm1'
Main m2 = m1;             // assign 'm2' to reference 'm1' (no new object)
Main m3 = new Main();     // create new Main object 'm3'
m2.num = 60;              // assign a field in 'm2' (no new object)
gacemarks(m2);            // repeatedly increment the 'm2.num' field (no new object)
System.out.println(m2);   // print 'm2' (no new object)

因此,对该方法的调用不会创建新对象,而是在传递的同一对象引用上工作。 - Nemaly Praveen
@NemalyPraveen 是的,没错。至少,当你引用字段 num 时,你正在增加作为参数传递的对象的字段。 - Tim Biegeleisen
@NemalyPraveen,你可能听说过Java是按值调用的,这可能让你感到困惑。这是正确的,但有一个问题:当你传递一个对象的引用时,例如在gacemarks(m2);中,值本身就是引用,即mm2的副本,但它们都只是指向同一个对象的引用(类似于C++中的指针)。 - Thomas
是的,@Thomas,这些可以被称为按值传递的对象引用。 - Nemaly Praveen

2

答案是2。

我们一起来数一数:

第一个对象:m1被创建了。

第二个对象:m2与上一个对象相同。

没有新的对象被添加,总数仍为1。

第三个对象:m3被新创建了。

在调用之后,没有m对象被生成。当您将m2传递给其他方法时,不会创建副本。因此,最终数量保持为2。

原始答案翻译成中文是"最初的回答"。


那么,你所说的代码是指主方法吗? - Nemaly Praveen
@NemalyPraveen,他指的是你所有的代码。m是对已传递对象的引用,因此它不是指向一个_新_对象。 - Thomas
@NemalyPraveen 是的,那就是所有操作发生的地方。除非 main 直接或间接调用它,否则不会执行任何代码。 - Sergey Kalinichenko

2

尽管代码中直接创建了两个Main对象(使用new运算符),但可以认为System.out.println(m2);由于调用了toString()而创建了一个额外的String对象。


好的发现 +1。也许这应该成为一个面试问题。 - Tim Biegeleisen
@TimBiegeleisen 另一个可能是在调用 main() 时创建的 String[] args 数组。很难确定问题的真正含义。 - Karol Dowbecki
实际上,你正在打开一个潘多拉魔盒,因为你不知道有多少对象被创建了。这取决于具体的实现方式。在Integer.toHexString()中创建了一个字符串,然后将其与其他内容(可能会创建或不创建对象的类名)连接起来,以创建另一个字符串。 - RealSkeptic
我理解“答案是2。但我得到了3。”的意思是“正确答案是2。但我得到了错误的3。”- 所以我怀疑所有其他对象,包括字符串,是否都被考虑在内。 :) - Thomas
我猜它通常指的是用户创建的对象,而不是自动生成的对象。 - Nemaly Praveen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接