在引用变量上调用方法与在新对象上调用方法

Calling methods on reference variable vs Calling methods on a new object

我在调用 非静态 方法时感到困惑

class A {
    void doThis() {}

    public static void main(String... arg) {
        A a1 = new A();
        a1.doThis();        // method - 1
        new A().doThis();   // method - 2
    }
}

我知道 method-1method-2 都会调用 doThis(),但有什么功能上的区别吗?

让我们看看代码用简单的英语说了什么:

      A a1 = new A();
      a1.doThis();
  1. 创建 A 的新实例。
  2. 在变量 a1 中存储对它的引用。
  3. 在我们的实例上调用 doThis()

new A().doThis(); 读作:

  1. 创建 A 的新实例。
  2. 在我们的实例上调用 doThis()

所以唯一的区别是你是否将它存储在局部变量中。如果您不再使用变量中的值,那么这种差异就无关紧要了。但是如果你想在同一个对象上调用另一个方法,比方说a1.doThat(),那么你在使用第二种解决方案时遇到了麻烦,因为你没有得到引用到原始实例。

为什么要使用同一个对象?因为方法可以改变对象的内部状态,所以这几乎就是对象的意义所在。

Is there any functional difference?

两者的行为方式相同。

第二个选项不允许您再次使用该实例。在 one-line return 语句中可能方便简洁(例如,考虑构建器模式,其中每个构造方法 return 是一个 half-initialised 实例):

return new Builder().a().b().build();

或者如果创建对象只是为了执行一次定义的操作。

What will be the reference of a new object in method-2?

它不再存在(更准确地说,我们无法访问它)除非 doThis returns this 您可以在方法执行后将其放入变量中。

Can I say that method-2 is an improper way of calling a non-static method?

没有。如果以后永远不会使用这个变量,为什么还要创建一个变量?

让我们一一了解这两种方法。

方法一

A a1 = new A();
a1.doThis();

method-1 中,您有一个新创建的 A 实例的引用,即 a1,您可以在此调用尽可能多的方法A 的实例使用此引用 a1。基本上,您可以通过使用其引用 a1.

来重用 A 的特定实例

方法二

new A().doThis();

但是在 method-2 中,您没有任何变量来存储新创建的 A 实例的引用。如果您必须在 A 的特定实例上调用任何其他方法,您将如何引用 A 的特定实例?如果您使用 method-2 创建一个实例,您将无法 re-use A 的那个实例,并且您将在使用该实例后立即丢失该实例。

这些方法的执行不会有任何区别,但在 new A().doThis() 的情况下,您将失去对您调用该方法的对象实例的引用,而您赢了' 能够在您的代码中进一步使用它。此方法可能对实例的内部状态所做的所有更改都将丢失。

A a1 = new A(); a1.doThis(); 的情况下,您将保留对象的实例(在变量 a1 中)以及方法 doThis() 对其状态所做的潜在更改。然后你就可以继续使用这个对象了。

案例 1:

 A a1 = new A();
 a1.doThis(); 

上面两行表示创建对象和doThis();已执行但对象在堆内存中仍然可用。

案例2:

new A().doThis();

创建了一个 class 对象并 doThis(); 立即执行 GC(GarbageColletor) 将激活以从堆内存中删除 A 对象,因为它是一个未引用的对象,我们可以调用该对象作为匿名对象。