在循环中创建对象

2022-09-01 20:27:39

在循环中创建对象是否是一种很好的做法。我指向以下代码:

for(some condition){
    SomeClass a = new SomeClass ();
    System.out.println(a);
}

因此,这将为每次迭代创建一个新的 SomeClass 实例。因此,实例数将等于迭代次数。然后这些稍后将由GC收集。

在循环中重用 SomeClass 对象是否更好。像这样:

SomeClass a = null;

for(some condition) {
    a = new SomeClass();
    System.out.println(a);
}

据我所知,第二种方法更好,因为这只会创建一次SomeClass对象,并在每次迭代中重用它。但我对此表示怀疑。请确认这一点,或者让我知道我的基本面在哪里不正确。


答案 1

不同之处在于,在第二种情况下,当循环结束时,变量仍将在作用域内。a

除此之外,即使从垃圾收集的角度来看,它们本质上是相同的。

字符串是引用类型(尽管是不可变的),无论你是为它们声明一个新变量,还是每次都覆盖相同的变量,这并不重要。您每次都仍在创建一个全新的字符串。


答案 2

请注意,不要混淆“对象”本身和对“对象”的“引用”:

例如,以下代码创建一个 (null) 引用,但不创建任何对象。

Object a = null;

下面的代码创建一个 Object 和对该对象的引用(引用保存在一个名为'a'的变量中):

Object a = new Object();

下面的代码创建新的 Object 并“重新指向”现有(引用)变量以指向新对象:如果变量 'a' 已经包含另一个引用,则 'a' 会忘记它。[但这并不意味着其他变量可能仍然指向'a'引用的旧对象]。

a = new Object(); // it is the reference 'a' that is 're-used' here not the object...

每次您在循环中重新运行上面的语句时;你确实在创建一个新对象;并且您正在“重新指向”“a”到该新对象。

以前的引用(即保存在“a”中的引用)每次都会被遗忘;和(假设我们在这里有一个单线程程序)这意味着它指向的对象现在将没有指向它的引用:这意味着该对象有资格进行垃圾回收。这个垃圾回收是否发生在这个时间点 - 我不知道我害怕。

但是我要说:就垃圾回收发生的时间而言,您的编码示例没有区别;无论“指针类型”是否已在循环外部定义为“对象”,还是在循环中重复重新定义。

以下(无用的)示例可能有助于说明代码一次性执行的“创建对象”和“引用点”操作之间的区别:

// This creates an object ; but we don't hold a reference to it.
    public class TestClass {
    public static void main(String[] args) {
    for (int n=0;n<100;n++) {
        new Object();
    }
    }
    }

对比一下:

// This creates a reference ; but no object is created
// This is identical to setting the reference to 'null'.
public class TestClass {
public static void main(String[] args) {
for (int n=0;n<100;n++) {
        Object o;
}
}
}