【问题标题】:Using new keyword without defining variable in java在java中使用new关键字而不定义变量
【发布时间】:2021-02-28 00:02:43
【问题描述】:

以下代码用于在变量中创建类的对象:

ClassName obj = new ClassName();

但是如果我们不创建任何变量而只输入以下内容呢?

new ClassName();

当我使用它时,没有错误。但是当没有创建变量时它实际上做了什么?

【问题讨论】:

  • 确实创建了一个对象。
  • 它创建了一个对象。该对象是否被变量引用完全是另一回事。

标签: java object instantiation


【解决方案1】:

两种方法都创建一个对象,但第二种方法没有名称。

当您创建 ClassName 的实例时,您的第一种方法和第二种方法之间的区别在于,对于您的第一种方法,您实际上可以访问类中的变量和方法。

例如,

ClassName obj = new ClassName();
System.out.println(obj.x);

类名在哪里

class ClassName {
    public static int x = 2;
}

这种方法的好处是您可以访问类中的变量。如果您使用第二种方法,那么实例将没有名称,因此您将无法访问变量。

【讨论】:

  • 真正使用第二种方法,如果您在对象创建中内联进行操作,例如System.out.println(new ClassName().x),您还可以访问变量和方法
  • 当然可以,但您只能执行一次。想象一下,如果您想在代码的 2 个不同部分找到 2 个不同的值。比如也许你想得到 x 并用它做一些数学运算,最后得到另一个变量。为了演示,我以此为例
  • 当然,如果您需要在不同的点使用创建的对象,在对象范围内,您需要定义一个变量以便重用它并多次访问变量和方法,所以第一种方法是正确的。但是当你写If you used the second approach .... you wouldn't be able to access the variables. 时,这可能会使 OP 感到困惑,因为正如我在评论中指出的那样,这确实是可能的,这可能很有用,例如,如果你想避免定义一个你只会在那时使用一次的对象变量也提高垃圾收集器效率
  • 是的。我的错,我只是用它作为一个例子来简化方法。
【解决方案2】:

new ClassName() 调用称为构造函数的特殊方法,并且与任何方法一样,它返回一个值1。它返回的值是ClassName 的一个实例。您可以选择将该值分配给变量,也可以不分配,就像您可以处理任何方法的返回值一样。因此,您只需要决定是否需要将返回值分配给变量。如果你这样做,那么你需要第一个语句,即:

ClassName obj = new ClassName();

如果你不需要将返回的值赋给变量,那么你可以使用:

new ClassName();

1 - 一个方法可以返回 void 这意味着它实际上并不返回一个值

【讨论】:

    【解决方案3】:

    为了回答您的问题,我认为了解 JVM 在执行期间如何管理对象很有用。

    所有java 对象都驻留在一个称为heap的JVM区域中并且可以(注意这不是强制性的)被一个或多个指向变量。 保存对对象的引用的变量位于 JVM 的另一个称为 stack 的区域。

    每次执行像new SomeClass(); 这样的指令时,都会在该区域分配一个新对象。当堆区域变满时,垃圾会被收集,并在垃圾收集期间清除不再由变量指向的对象,以便为新对象释放堆空间。

    你的两条指令有什么区别?

    1-ClassName obj = new ClassName();

    它在堆上分配一个由堆栈上的obj变量指向的新对象。

    2-new ClassName();

    它只是在堆上分配一个新对象,堆栈上没有指向它的变量。

    什么时候可以使用第二种方法?

    据此,如果您只想在堆上分配一个新对象而不通过变量使用它,例如测试程序的内存管理,则使用第二种方法可能很有用。实际上,当您想创建一个“一次性”对象并在同一条指令中使用它的方法或变量时,使用第二种方法可以提高垃圾收集器的效率并避免意外获得 OutOfMemoryError 异常,例如:

    • 使用一次对象变量:
    System.out.println(new ClassName().x)
    

    • 执行一次对象方法:
    new ClassName().evaluateResult();
    

    注意:在这种特定情况下,您可能可以进行评估以在类上创建一个静态方法

    另一种用法是将新元素放入集合中,如下所示:

    final List<ClassName> objectList = new ArrayList<>();
    for(int i=0; i<10; i++){
      objectList.add(new ClassName());
    }
    

    你可能会问:如果被指向的对象会发生什么? 至少有一个变量类似于第一种方法创建的变量?

    当变量超出范围时,变量中的所有引用自然会被删除,因此它们自动符合垃圾收集的条件(根据它们的范围在代码上的管理方式)。

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2012-08-12
      • 1970-01-01
      • 2016-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多