24

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.

20
  • 3
    String literals are not best example here because of string pool. Also both your examples creates "new instance" in each loop iteration. Commented Feb 18, 2014 at 17:09
  • Okay, now I undesrand that, so what about Sets and Lists. What would be the difference if I create a Set object inside loop or outside loop? Commented Feb 18, 2014 at 17:10
  • They are objects, just like String. They behave exactly the same from this point of view. Commented Feb 18, 2014 at 17:11
  • 1
    Neither example creates an object. Declaring a reference is not the same as creating an object, and string literals are pre-created. Commented Feb 18, 2014 at 17:11
  • 1
    @Pshemo - Yes, unless the user has some use for a outside the loop, it makes no difference which he chooses. Even if there is a very slight difference in the generated code it would have negligible effect on performance (and no effect on GC). Commented Feb 18, 2014 at 18:14

9 Answers 9

17

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Please clarify "creating a brand new string every time". I don't recall any version of the OP's code that created any strings.
Actually, no, the OP did not edit it, someone else did. And if you check the edit history there was never a version that did a new String operation.
@SamIam does the declaration (of a variable) in each iteration have any overhead? Or is it still the same.
@OptimusPrime If there is overhead, there's not enough for you to notice a difference.
6

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

1 Comment

Correction: None of the statements create a new object, because referencing a String literal does not create a new object.
5

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!

5 Comments

Both create the same amount of strings because neither creates any.
@HotLicks What on earth are you rambling about?
In the original code (since edited) no strings were created anywhere. "foo" was a string literal that pre-existed.
@HotLicks I had zero code in my original answer, so I assume you just misplaced your comment.
I was talking about the original question. It's been edited to be totally different from the first version.
3

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.

1 Comment

Good point about the specific behaviour or strings with regard to them being pooled....
3

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.

Comments

3

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

3 Comments

It is quite unwise to use static anything without thinking about it carefully.
@Hot Licks- Thank you for your opinion.
An opinion backed by 40 years of programming.
3

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

Comments

2

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

11 Comments

a="foo" =\= new String("foo")
a = "foo" assigns the pre-created, JVM-global String instance of "foo" to the reference. So nothing is created.
What is the difference then?
The difference between "foo" and new String("foo")? The latter does create a new String object.
@SebastianH String a ="foo" here "foo" is a string literal and stored in java string pool. if you try to assign same literal into another reference, it will get same reference from string pool. but new string(..) returns a object of string type
|
2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.