Sambhav Sharma
Sambhav Sharma

Reputation: 5860

Creating an Object inside a loop

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.

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

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.

Upvotes: 24

Views: 49904

Answers (9)

monojohnny
monojohnny

Reputation: 6181

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'):

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 other variables may still point to the old object referenced by '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.

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.

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

Upvotes: 6

Girish
Girish

Reputation: 1717

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

Upvotes: 3

user902383
user902383

Reputation: 8640

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 someFunction while for first method, its lifecycle is within single iteration of loop

Upvotes: 2

DRastislav
DRastislav

Reputation: 1882

according to my knowledge - in bigger application (not in this) but in bigger is better to use static block for 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

remember: Static block can access only static variables and methods

Upvotes: 3

Zavior
Zavior

Reputation: 6452

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.

Upvotes: 3

Kent
Kent

Reputation: 195129

the 2nd is not "better".

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

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

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

It creates new object in each loop step. a is 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.

Upvotes: 3

SebastianH
SebastianH

Reputation: 2182

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

If you really want to reuse the 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).

Upvotes: 2

Rainbolt
Rainbolt

Reputation: 3660

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

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

Option 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.

Option 2

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

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

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

Upvotes: 5

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

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.

Upvotes: 17

Related Questions