Creating an Object inside a loop

44,215

Solution 1

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.

Solution 2

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!

Solution 3

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

Solution 4

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

Solution 5

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.

Share:
44,215

Related videos on Youtube

Sambhav Sharma
Author by

Sambhav Sharma

#SOreadytohelp Backend Developer, Part time DevOps, Enthusiast, Coder

Updated on July 09, 2022

Comments

  • Sambhav Sharma
    Sambhav Sharma almost 2 years

    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.

    • Pshemo
      Pshemo about 10 years
      String literals are not best example here because of string pool. Also both your examples creates "new instance" in each loop iteration.
    • Sambhav Sharma
      Sambhav Sharma about 10 years
      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?
    • Zavior
      Zavior about 10 years
      They are objects, just like String. They behave exactly the same from this point of view.
    • Hot Licks
      Hot Licks about 10 years
      Neither example creates an object. Declaring a reference is not the same as creating an object, and string literals are pre-created.
    • Konza
      Konza about 10 years
      String is immutable :)
    • Hot Licks
      Hot Licks about 10 years
      And, as edited, both create the same number of objects. (Count the new operations.)
    • Pshemo
      Pshemo about 10 years
      @SambhavSharma I edited your examples a little to get rid of string pooling problem. Feel free to rollback my edits if they express your question correctly.
    • Hot Licks
      Hot Licks about 10 years
      @Pshemo -- I think that was a bad idea, since it invalidated numerous comments and answers. Better to insert NEW examples.
    • Sambhav Sharma
      Sambhav Sharma about 10 years
      This was very helpful. One basic thing is String is immutable, and in case of String, in neither of the case an object will be created. And anyways, in general object cases, both will create equal number of objects. I think I understood this well..
    • Pshemo
      Pshemo about 10 years
      Can someone confirm or deny that both loops will be optimized by JIT to behave the same?
    • Hot Licks
      Hot Licks about 10 years
      The fact that no objects were created in the original version has relatively little to do with the fact that String is immutable and a lot to do with the fact that there were simply no new operations in the loops.
    • Hot Licks
      Hot Licks about 10 years
      Not quite the same. The stack location for a will be allocated after any loop control values in the first case, before them in the second case. This reflects the difference in scope of the two variables.
    • Pshemo
      Pshemo about 10 years
      @HotLicks I assume that your last comment was for me. From examples it seems that OP uses new instances only inside loops. Is JIT smart enough to notice this and use this info to optimize both examples to act the same? I am just asking from curiosity, because it seems like possible thing.
    • Hot Licks
      Hot Licks about 10 years
      @Pshemo - Other than the difference in reference scope there's no difference between the function of the two loops, and nothing much for the JITC to optimize.
    • Pshemo
      Pshemo about 10 years
      @HotLicks Yes, so assuming that a will never be used outside loop, both loops will most likely (after JIT kicks in) be optimized to behave the same, so it doesn't matter which version we will chose, so this question is kind of pointless (again, in situation where a is used only inside loops). Correct me if I am wrong.
    • Hot Licks
      Hot Licks about 10 years
      @Pshemo - I wouldn't say the question is pointless -- it exposed an awful lot of ignorance.
    • Hot Licks
      Hot Licks about 10 years
      This question appears to be off-topic because it has morphed beyond recognition, making many of the comments and answers confused if not completely wrong.
    • Pshemo
      Pshemo about 10 years
      @HotLicks OK, maybe I said it wrong. I like this question. It is very interesting one. What I meant by pointless was fact that it will not matter which option we will chose. Maybe I used wrong term (English is not my native language and I am using it only on SO, so sorry if my words are not 100% accurate).
    • Hot Licks
      Hot Licks about 10 years
      @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).
    • Ashis Parajuli
      Ashis Parajuli over 7 years
      I support this question, I was also getting confused on this .
  • Hot Licks
    Hot Licks about 10 years
    Both create the same amount of strings because neither creates any.
  • Kent
    Kent about 10 years
    a="foo" =\= new String("foo")
  • Rainbolt
    Rainbolt about 10 years
    @HotLicks What on earth are you rambling about?
  • Hot Licks
    Hot Licks about 10 years
    a = "foo" assigns the pre-created, JVM-global String instance of "foo" to the reference. So nothing is created.
  • SebastianH
    SebastianH about 10 years
    What is the difference then?
  • Hot Licks
    Hot Licks about 10 years
    In the original code (since edited) no strings were created anywhere. "foo" was a string literal that pre-existed.
  • Hot Licks
    Hot Licks about 10 years
    The difference between "foo" and new String("foo")? The latter does create a new String object.
  • monojohnny
    monojohnny about 10 years
    Good point about the specific behaviour or strings with regard to them being pooled....
  • Rainbolt
    Rainbolt about 10 years
    @HotLicks I had zero code in my original answer, so I assume you just misplaced your comment.
  • Hot Licks
    Hot Licks about 10 years
    It is quite unwise to use static anything without thinking about it carefully.
  • java seeker
    java seeker about 10 years
    @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
  • Hot Licks
    Hot Licks about 10 years
    I was talking about the original question. It's been edited to be totally different from the first version.
  • Sambhav Sharma
    Sambhav Sharma about 10 years
    But String a = "foo" will also create an object, right? Like you said earlier, or you mean to say that it will create a reference because of String being immutable?
  • Sambhav Sharma
    Sambhav Sharma about 10 years
    Okay @javaseeker already cleared my doubt, sorry for the delay in asking the question!
  • Hot Licks
    Hot Licks about 10 years
    @SambhavSharma No, assigning a reference to a variable does not create an object. You need to understand the critical distinction between references(pointers) and objects.
  • DRastislav
    DRastislav about 10 years
    @Hot Licks- Thank you for your opinion.
  • Hot Licks
    Hot Licks about 10 years
    An opinion backed by 40 years of programming.
  • java seeker
    java seeker about 10 years
    @SambhavSharma string object is immutable not the reference.
  • Hot Licks
    Hot Licks about 10 years
    Correction: None of the statements create a new object, because referencing a String literal does not create a new object.
  • Hot Licks
    Hot Licks about 10 years
    Please clarify "creating a brand new string every time". I don't recall any version of the OP's code that created any strings.
  • Hot Licks
    Hot Licks about 10 years
    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.
  • monojohnny
    monojohnny about 10 years
    Isn't there some confusion between immutable objects in general and the specific case of String objects ? I thought the JVM just contained specialized mechanisms (pooling) for strings ? Is the JVM smart enough to pool any immutable objects ? Is it safe for it to assume that a programmer has correctly implemented equals and hash code for the purposes of pooling? Is there any specific language feature which marks an object 'immutable' ? The only way I have managed this in java is by carefully following certain patterns ? (Private constructor and other requirements?)
  • SebastianH
    SebastianH about 10 years
    @monojohnny The confusion here might arise from the history of the question. The question initially only asked about the handling of Strings, but was later changed to ask about Objects in general. Therefore I completely changed my answer as well - especially since I obviously made mistakes in my first answer.
  • Optimus Prime
    Optimus Prime about 5 years
    @SamIam does the declaration (of a variable) in each iteration have any overhead? Or is it still the same.
  • Sam I am says Reinstate Monica
    Sam I am says Reinstate Monica about 5 years
    @OptimusPrime If there is overhead, there's not enough for you to notice a difference.