Java 在循环内创建对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21860573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:07:18  来源:igfitidea点击:

Creating an Object inside a loop

javaooploopsobject

提问by Sambhav Sharma

Is it a good practice to create an Object inside a loop. I am pointing towards the following code:

在循环内创建对象是一个好习惯。我指向以下代码:

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

So this would create a new instance of SomeClass for each iteration. So number of instances will be equal to number of iterations. And then these will later be collected by GC.

所以这将为每次迭代创建一个新的 SomeClass 实例。所以实例数将等于迭代次数。然后这些稍后将被 GC 收集。

Is it better to reuse a SomeClass object inside the loop. Something like this:

在循环内重用 SomeClass 对象是否更好。像这样的东西:

SomeClass a = null;

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

As far as I understand this, the second way is better as this will just create the SomeClass object once and will reuse it in every iteration. But I am doubtful. Please confirm this, or let me know where my fundamentals are incorrect.

据我了解,第二种方法更好,因为这只会创建 SomeClass 对象一次,并会在每次迭代中重用它。但我很怀疑。请确认这一点,或者让我知道我的基本原理不正确的地方。

采纳答案by Sam I am says Reinstate Monica

The difference is that in your second case, your avariable will still be in scope when the loop is over

不同之处在于,在您的第二种情况下,a当循环结束时,您的变量仍将在范围内

other than that, they're essentially the same, even from a garbage collection point of view.

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

Strings are reference types(albeit immutable ones), and it doesn't really matter whether you declare a new variable for them or just overwrite the same variable each time. You're still creating a brand new string every time.

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

回答by Zavior

You are confusing the variable you assign an object to, to the actual object instance.

您将对象分配给的变量与实际的对象实例混淆了。

Both code samples create the equivalent amount of objects. The second one will keep one instance in larger scope, thus it will be available for a longer time.

两个代码示例都创建了等量的对象。第二个会将一个实例保留在更大的范围内,因此它可以使用更长的时间。

回答by Rainbolt

Both create an equivalent amount of strings because Stringis immutable. Anytime a Stringis assigned a new value, a new Stringis created.

两者都创建了等量的字符串,因为它们String是不可变的。任何时候为 aString分配一个新值,String都会创建一个新值。

Let's assume you meant to use a mutable object in your example.

假设您打算在示例中使用可变对象。

Option 1

选项1

for(some condition)
{
    Object o = new Object();
    System.out.println(o);
}

This will create a new Object o for each iteration of the loop.

这将为循环的每次迭代创建一个新对象 o。

Option 2

选项 2

Object o;
for(some condition)
{
    o = new Object();
    System.out.println(o);
}

This will create a new Objecto for each iteration of the loop.

这将为Object循环的每次迭代创建一个新的o。

Even for a mutable object, you get the same result either way!

即使对于可变对象,无论哪种方式,您都会得到相同的结果!

回答by Kent

the 2nd is not "better".

第二个不是“更好”。

String a="foo";reuse a literal string from string pool. That is, no matter you declare the ain/outside the loop, there is no difference in terms of memory. But they have different scope. I think it is another issue.

String a="foo";重用字符串池中的文字字符串。也就是说,无论你声明ain/ loopout of the ,在内存方面都没有区别。但它们的范围不同。我认为这是另一个问题。

even if with your edited version, with general SomeClass, it is not like what you thought:

即使使用您编辑过的版本,使用 general SomeClass,它也不像您想的那样:

the second way is better as this will just create the SomeClass object once and will reuse it in every iteration .

第二种方法更好,因为这只会创建 SomeClass 对象一次,并将在每次迭代中重用它。

It creates new object in each loop step. ais just a reference to the object. The point is, if the object(s) you created referenced by other objects, GC will not collect it, and release the memory. For example, the old (<=java1.6) String.subString() method, it holds the original String as char[], so GC won't clean the original String.

它在每个循环步骤中创建新对象。a只是对对象的引用。关键是,如果您创建的对象被其他对象引用,GC 不会收集它,并释放内存。例如,旧的 (<=java1.6) String.subString() 方法,它将原始 String 保存为char[],因此 GC 不会清理原始 String。

回答by Girish

The only difference is that in the second case, variable will still be in scope when the loop is over ,no. of objects that are created in both the cases are equal as Strings are immutable

唯一的区别是在第二种情况下,当循环结束时,变量仍然在范围内,不。在这两种情况下创建的对象的数量相等,因为字符串是不可变的

as you have just edit the question still in this case new Objects are created in the memory at each iteration in both the cases

因为您刚刚编辑了问题,在这种情况下,在这两种情况下,每次迭代都会在内存中创建新对象

回答by SebastianH

Since the topic has changed quite a bit. I update:

由于主题已经改变了很多。我更新:

If you really want to reusethe once create object you will have to write that code yourself. It could follow this principle:

如果您真的想重用曾经创建的对象,则必须自己编写该代码。它可以遵循这个原则:

SomeClass a = new SomeClass();

for(some condition) {
    a.reset();
    //do something with a
}

Where the SomeClass.reset()method handles all the details (which are dependant on your actual usage of the object).

SomeClass.reset()方法处理所有的细节(这依赖于对象的实际使用情况)。

回答by monojohnny

Be careful not confuse the 'Object' itself and a 'Reference' to an 'Object':

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

For instance the following code creates a (null) Reference, but no object is created.

例如,下面的代码创建一个(空)引用,但没有创建对象。

Object a = null;

The following code create boths an Object AND a reference to that object (the reference is held in a variable called 'a'):

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

Object a = new Object();

The following code creates new Object and 'repoints' an existing (reference) variable to point to the new Object: if the variable 'a' already held another reference, 'a' forgots it. [but that doesn't mean othervariables may still point to the old object referenced by 'a'].

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

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

Everytime you re-run the that statement above in your loop; you are indeed creating a new object ; and you are 're-pointing' 'a' to that new object.

每次在循环中重新运行上述语句时;您确实在创建一个新对象;并且您将“重新指向”“a”指向那个新对象。

The previous reference (i.e. reference held in 'a') will be forgotten each time; and (assuming we have a single-threaded program here) that means the object it pointed to will have zero references pointing at it now: which means the object is eligible for Garbage Collection. Whether this Garbage collection happens or not at this point in time - I don't know I'm afraid.

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

But I would say : that there is no difference in your coding examples in terms of when Garbage Collection happens; whether or not the 'pointer-type' is already defined as an 'Object' outside of the loop, or repeatedly redefined within the loop.

但我想说:就垃圾收集发生的时间而言,您的编码示例没有区别;“指针类型”是否已经在循环外定义为“对象”,或者是否在循环内重复重新定义。

The following (useless) examples might help illustrate the difference between the 'Create-an-Object' and 'Point-a-Reference' actions that the code does in one go:

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

// 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();
    }
    }
    }

And to contrast:

并对比:

// 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;
}
}
}

回答by DRastislav

according to my knowledge - in bigger application (not in this) but in bigger is better to use static blockfor object creation - because static block code is executed only once when class is loaded into memory. Technically, you can can have multiple static blocks in a class, although it doesn't make much sense

根据我的知识 - 在更大的应用程序中(不在此)但在更大的应用程序中更好地 static block用于对象创建 - 因为静态块代码仅在类加载到内存时执行一次。从技术上讲,您可以在一个类中拥有多个静态块,尽管这没有多大意义

remember: Static block can access only static variables and methods

记住: Static block can access only static variables and methods

回答by user902383

it is all about scope,

一切都与范围有关,

if you do your second way:

如果您采用第二种方式:

SomeType someFunction(){
   ...
    SomeClass a = null;

    for(some condition) {
        a = new SomeClass();


           System.out.println(a);
        }
     ...
     return something
    }

object a will exist in memory till end of someFunctionwhile for first method, its lifecycle is within single iteration of loop

someFunction对于第一个方法,对象 a 将存在于内存中直到while结束,其生命周期在循环的单次迭代中