12

Ive got one simple question. Normally I write code like this:

String myString = "hello";

for (int i=0, i<10; i++)
{
  myString = "hello again";
}

Because I think the following would not be good style cause it would create too many unnecessary objects.

for (int i=0, i<10; i++)
{
  String myString = "hello again";
}

Is this even correct? Or is this just the case when Ive got an explicit object like an object from a class I created? What if it was a boolean or an int? What is better coding style? Instantiate it once before the loop and use it in the loop or instantiate it every time in the loop again? And why? Because the program is faster or less storage is used or...?

Some one told me, if it was a boolean I should instantiate it directly in the loop. He said it would not make a difference for the heap and it would be more clear that the variable belongs inside the loop. So what is correct?

Thanks for an answer! :-)

====

Thanks for all your answers!

In conclusion: it is preferable to declare an object inside the smallest scope possible. There are no performance improvements by declaring and instantiating objects outside the loop, even if in every looping the object is reinstantiated.

trincot
  • 317,000
  • 35
  • 244
  • 286
nano7
  • 2,455
  • 7
  • 35
  • 52
  • if you declare the variable inside of the loop (like in the second example) that variable only has scope inside of that loop. So if you want to use it before/after the loop you'll have to declare it outside of the loop. However, you don't have to instantiate it outside of the loop. – twain249 May 09 '12 at 19:38

7 Answers7

15

No, the latter code isn't actually valid. It would be with braces though:

for (int i=0; i<10; i++)
{
    String myString = "hello again";
}

(Basically you can't use a variable declaration as a single-statement body for an if statement, a loop etc.)

It would be pointless, but valid - and preferable to the first version, IMO. It takes no more memory, but it's generally a good idea to give your local variables the narrowest scope you can, declaring as late as you can, ideally initializing at the same point. It makes it clearer where each variable can be used.

Of course, if you need to refer to the variable outside the loop (before or afterwards) then you'll need to declare it outside the loop too.

You need to differentiate between variables and objects when you consider efficiency. The above code uses at most one object - the String object referred to by the literal "hello again".

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • This is the only correct answer; try to restrict the scope of your variables as much as possible. – Sanjay T. Sharma May 09 '12 at 19:39
  • So, no matter which kind of object or variable or data type I use: int, String, Object - if I only use it in the loop I should always instantiate it in the loop? For example, if I use "Object" and I want to give the object every time in the loop a new value - it really would not be better to the declare the object once outside the loop??? – nano7 May 09 '12 at 19:46
  • @nano7 Correct, it would not be better. After all, each iteration of the loop is assigning a new object to the reference, right? So how can that be worse than doing that, plus an additional assignment later? This is the same principle that has you (correctly) writing `for (int i=0; ...)` instead of `int i=0; for(i = 0; ... )`. – yshavit May 09 '12 at 19:51
  • 2
    @nano7: Yup - it would be more efficient if you wanted to use the same value for *all* iterations of the loop, but if you're going to assign a new value on each iteration anyway, declare it inside the loop. – Jon Skeet May 09 '12 at 19:53
3

As Binyamin Sharet mentioned, you generally want to declare a variable within the smallest scope possible. In your specific examples, the second one is generally preferable unless you need access to the variable outside your loop.

However, under certain conditions this can have performance implications--namely, if you are instantiating the same object over and over again. In your particular example, you benefit from Java's automatic pooling of String literals. But suppose you were actually creating a new instance of the same object on every iteration of the loop, and this loop was being executed hundreds or thousands of times:

for (int i=0, i<1000; i++)
{
  String myString = new String("hello again"); // 1000 Strings are created--one on every iteration
  ...
}

If your loop is looping hundreds or thousands of times but it just so happens that you're instantiating the same object over and over again, instantiating it inside the loop is going to result in a lot of unnecessary garbage collection, because you create and throw away a new object on every iteration. In that case, you would be better off declaring and instantiating the variable once outside of the loop:

String myString = new String("hello again"); // only one String is created

for (int i=0, i<1000; i++)
{
  ...
}

And, to come full circle, you can manually limit the scope by adding extra braces around the relevant section of code:

{ // Limit the scope
  String myString = new String("hello again");

  for (int i=0, i<1000; i++)
  {
    ...
  }
}
rob
  • 6,147
  • 2
  • 37
  • 56
  • Hm. What if I want to have a new object in each looping with a different value. Would it then be like this? String myString; for (int i=0, i<1000; i++) { myString = newString(differentValue); } I guess this would be the most efficient then, correct? Or doesn't it make any difference if I would write String myString = newString(differentValue) directly inside the loop? – nano7 May 09 '12 at 20:47
  • To clarify, I was only using the `new String(...)` constructor to take Java's built-in String literal pooling out of the equation. I can't remember the last time I explicitly used the String class' constructor. To answer your question: if you are creating a new immutable object on every iteration anyway, then you won't perceive any performance benefit by declaring the variable outside the loop vs. inside the loop. – rob May 09 '12 at 21:14
1

Seems like you mean declare, not instantiate and in general, you should declare a variable in the smallest scope required (in this case - in the loop).

MByD
  • 135,866
  • 28
  • 264
  • 277
1

if you are going to use the variable outside the for loop, then declare it out side, otherwise its better to keep the scope to minimum

Habib
  • 219,104
  • 29
  • 407
  • 436
1

The problem with the second is you create object and someone (the GC) has to clean them, of course for a 10 iteration it is unimportant.

BTW in your specific example I would have wrote

    String myString = null; 
    final String HELLO_AGAIN="hello again";
    for (int i=0; i<10; i++)
      myString = HELLO_AGAIN;
miks
  • 514
  • 2
  • 5
0

Unless value is changed, you should definitely instantiate outside of the loop.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
0

The problem here is that String is an immutable object: you cannot change the value of a string, only you can create new String objects. Either way, if your goal is to assign a variable a new object instance, then limit your scope and declare it inside the body of your loop.

If your object is mutable, then it would be reasonable to reuse the object in every next iteration of the loop, and just change those attributes you need. This concept is used to run the same query multiple times, but with different parameters, you use a PreparedStatement.

In the extreme case, you would even maintain pools of objects which can be shared within the whole application. You create additional objects as you run out of resources, you shrink if you detect a reasonable amount of non-use. This concept is used to maintain a Connection Pool.

YoYo
  • 9,157
  • 8
  • 57
  • 74