Why does this work fine:
str = calculateStr();
String str = calculateStr();
In your example I presume
str is not used outside of the
while loop, otherwise you would not be asking the question, because declaring it inside the
while loop would not be an option, since it would not compile.
str is not used outside the loop, the smallest possible scope for
str is within the while loop.
So, the answer is emphatically that
str absolutely ought to be declared within the while loop. No ifs, no ands, no buts.
The only case where this rule might be violated is if for some reason it is of vital importance that every clock cycle must be squeezed out of the code, in which case you might want to consider instantiating something in an outer scope and reusing it instead of re-instantiating it on every iteration of an inner scope. However, this does not apply to your example, due to the immutability of strings in java: a new instance of str will always be created in the beginning of your loop and it will have to be thrown away at the end of it, so there is no possibility to optimize there.
EDIT: (this is something that I wrote in a comment below, but I think it is worth making part of the answer.)
In any case, the right way to do things is to write all your code properly, establish a performance requirement for your product, measure your final product against this requirement, and if it does not satisfy it, then go optimize things. And what usually ends up happening is that you find ways to provide some nice and formal algorithmic optimizations in just a couple of places which make our program meet its performance requirements instead of having to go all over your entire code base and tweak and hack things in order to squeeze clock cycles here and there.