这两种方式创建对象有什么区别?

3
我想知道这些之间的区别是什么:
1-)
JFrame frame = new JFrame();
JLabel label = new JLabel("example");
frame.add(label);

2-)

JFrame frame = new JFrame();
frame.add(new Label("example"));

另外,我们可以使用以下语法:
1-)
new Timer(10, new ActionListener() {...}).start();

但为什么我们不能像这样使用它:

2-)

Timer timer = new Timer(10, new ActionListener() {...}).start(); // we cannot use it this way it has to be like:

//Timer timer = new Timer(10, new ActionListener() {...});
//timer.start();

2
.start() 不会返回它被调用的计时器,它根本不会返回任何东西。 - Louis Wasserman
我想知道那个原因 :) - shanks
4个回答

3
这两者的区别在于,如果您在将对象作为参数传递给方法时不需要引用变量,则可以在调用方法时直接生成对象,例如:frame.add(new Label("example")); 但是,如果您确实需要作为参数传递的对象的引用变量,最好拥有它,以便以后的代码中可以对其进行操作。例如,如果您想要更改某些实例变量或在方法完成任务后获取Object的状态,在这种情况下,您将需要引用变量。
另外,对于您的另一个问题,答案由Ramanlfc提供,可以通过以下方式完成:new Timer(10, new ActionListener() {...}).start();。由于此处忽略了方法的返回类型,因此该语句将被执行。
Timer timer = new Timer(10, new ActionListener() {...}).start(); 

这是不可能的,因为start()方法没有返回一个Timer对象,而代码中却把它赋值给了Timer引用变量。


我明白了,谢谢。另外,在内存方面没有任何区别,对吧? - shanks
@shanks 无论哪种情况,您都将创建一个对象,因此在堆上占用的内存相同:),如果答案有帮助,请接受答案。 - Pankaj Nimgade
@shanks,非常感谢 :) - Pankaj Nimgade

2

Timer timer = new Timer(10, new ActionListener() {...}).start();

在赋值时,需要注意表达式是从右向左计算的,所以表达式的值应该能够赋值给等号左边的操作数。在这种情况下,start()方法将不会返回Timer,因此无法实现赋值。


1

其他答案是正确的。

另一种思考方式是,对new JLabel的调用会立即在内存中创建JLabel对象。仅在构建之后,该对象才被分配给您的JLabel label变量。 label变量不是您的JLabel对象。它是一个引用,一个可以将我们带到JLabel对象的名称。JLabel对象本身在某个地方漂浮在内存中。

宇航员系绳

JLabel对象就像太空行走中的宇航员。将该对象分配给label变量就像将宇航员的系绳末端放在您的手中。使用该label变量就像拉动系绳以到达宇航员。

你的备用代码向JFrame对象传递了一个对JLabel对象的引用。同样,在将JLabel对象移交给JFrame之前,该对象已经完整存在。移交后,本地代码已经“忘记”了JLabel。没有本地引用变量就没有办法回到JLabel对象。JLabel对象仍然存在于某个地方的内存中,但对于我们的本地代码来说是无法访问的。在我们的太空行走类比中,将引用移交给JFrame就像将宇航员的系绳交给其他人一样。
如果我们保持一个本地的JLabel引用变量,并将其移交给JFrame,那么就像给我们的太空行走宇航员连接两个系绳一样。你手里拿着一个系绳(本地变量),同时将第二个系绳(JFrame对象)传递给其他人。
如果所有的引用都被设置为null或超出作用域,那就像释放所有系绳一样。对象仍然在内存中存在一段时间,但成为垃圾收集的候选对象。实际上从内存中删除发生在垃圾回收器运行并决定回收该内存空间的时候。

1
在前两个例子中,您正在创建一个JFrame并将其分配给JFrame变量。标签也是如此。
Timer timer = new Timer(10, new ActionListener() {...}).start();

不会工作,因为返回类型是。
start();

是空的。
new Timer(10, new ActionListener() {...}).start();

这是因为您从未尝试将void返回值分配给计时器。


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