Creating an Object inside a loop
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.
Related videos on Youtube
Sambhav Sharma
#SOreadytohelp Backend Developer, Part time DevOps, Enthusiast, Coder
Updated on July 09, 2022Comments
-
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 about 10 yearsString literals are not best example here because of string pool. Also both your examples creates "new instance" in each loop iteration.
-
Sambhav Sharma about 10 yearsOkay, 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 about 10 yearsThey are objects, just like String. They behave exactly the same from this point of view.
-
Hot Licks about 10 yearsNeither example creates an object. Declaring a reference is not the same as creating an object, and string literals are pre-created.
-
Konza about 10 yearsString is immutable :)
-
Hot Licks about 10 yearsAnd, as edited, both create the same number of objects. (Count the
new
operations.) -
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 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 about 10 yearsThis 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 about 10 yearsCan someone confirm or deny that both loops will be optimized by JIT to behave the same?
-
Hot Licks about 10 yearsThe 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 about 10 yearsNot 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 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 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 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 wherea
is used only inside loops). Correct me if I am wrong. -
Hot Licks about 10 years@Pshemo - I wouldn't say the question is pointless -- it exposed an awful lot of ignorance.
-
Hot Licks about 10 yearsThis 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 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 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 over 7 yearsI support this question, I was also getting confused on this .
-
-
Hot Licks about 10 yearsBoth create the same amount of strings because neither creates any.
-
Kent about 10 years
a="foo" =\= new String("foo")
-
Rainbolt about 10 years@HotLicks What on earth are you rambling about?
-
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 about 10 yearsWhat is the difference then?
-
Hot Licks about 10 yearsIn the original code (since edited) no strings were created anywhere. "foo" was a string literal that pre-existed.
-
Hot Licks about 10 yearsThe difference between "foo" and
new String("foo")
? The latter does create a new String object. -
monojohnny about 10 yearsGood point about the specific behaviour or strings with regard to them being pooled....
-
Rainbolt about 10 years@HotLicks I had zero code in my original answer, so I assume you just misplaced your comment.
-
Hot Licks about 10 yearsIt is quite unwise to use static anything without thinking about it carefully.
-
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 about 10 yearsI was talking about the original question. It's been edited to be totally different from the first version.
-
Sambhav Sharma about 10 yearsBut 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 about 10 yearsOkay @javaseeker already cleared my doubt, sorry for the delay in asking the question!
-
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 about 10 years@Hot Licks- Thank you for your opinion.
-
Hot Licks about 10 yearsAn opinion backed by 40 years of programming.
-
java seeker about 10 years@SambhavSharma string object is immutable not the reference.
-
Hot Licks about 10 yearsCorrection: None of the statements create a new object, because referencing a String literal does not create a new object.
-
Hot Licks about 10 yearsPlease 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 about 10 yearsActually, 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 about 10 yearsIsn'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 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 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 about 5 years@OptimusPrime If there is overhead, there's not enough for you to notice a difference.