15

In Java it is possible to declare a variable in the initialization part of a for-loop:

for ( int i=0; i < 10; i++) {
  // do something (with i)
}

But with the while statement this seems not to be possible.

Quite often I see code like this, when the conditional for the while loop needs to be updated after every iteration:

List<Object> processables = retrieveProcessableItems(..); // initial fetch
while (processables.size() > 0) {
    // process items
    processables = retrieveProcessableItems(..); // update
}

Here on stackoverflow I found at least a solution to prevent the duplicate code of fetching the processable items:

List<Object> processables;
while ((processables = retrieveProcessableItems(..)).size() > 0) {
    // process items
}

But the variable still has to be declared outside the while-loop.

So, as I want to keep my variable scopes clean, is it possible to declare a variable within the while conditional, or is there some other solution for such cases?

5
  • There is a do-while loop which sounds like a good candidate in this case. The declaration will have to stay outside of the loop, but at least you will have only one assignment instead of two. Commented Aug 4, 2016 at 12:26
  • @JaroslawPawlak - So, where would be the difference to my final while example above? Commented Aug 4, 2016 at 12:30
  • Cleaner code. It wouldn't have assignment hidden in the boolean expression. Commented Aug 4, 2016 at 12:34
  • @JaroslawPawlak Could you provide an answer with an example? Right now I'm unable to imagine how you mean that. Commented Aug 4, 2016 at 12:43
  • There is no way to do such a thing, but you can try to use stream API to make your code functional style Commented Jan 13, 2023 at 13:35

3 Answers 3

24

You can write a while loop using a for loop:

while (condition) { ... }

is the same as

for (; condition; ) { ... }

since all three bits in the brackets of the basic for statement declaration are optional:

BasicForStatement:
    for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement

Similarly, you can just rewrite your while loop as a for loop:

for (List<Object> processables;
     (processables = retrieveProcessableItems(..)).size() > 0;) {
  // ... Process items.
}

Note that some static analysis tools (e.g. eclipse 4.5) might demand that an initial value is assigned to processables, e.g. List<Object> processables = null. This is incorrect, according to JLS; my version of javac does not complain if the variable is left initially unassigned.

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

10 Comments

Nicked your last idea. UV for sake of a clear conscience.
Sorry, the for-loop reintroduces the duplicate-code problem, since it is necesarry to update the processables in the increment part of the statement: for (List<Object> processables = retrieveProcessableItems(..); processables.size() > 0; processables = retrieveProcessableItems(..))
@Bathsheba sorry, I wasn't meaning to sound like I disbelieved you :) Like I say, I've just never had cause to declare a variable without initialization in the [ForInit]. Tried it, checked the spec; of course, you are right.
To me that's a defect in your IDE: it ought to know that something is always assigned to the variable before its contents are read. = null it is then.
@Bathsheba I've moved it out as a separate point, so it's easier to read the "not in error" answer. Thanks.
|
12

No it's not possible.

It doesn't really make too much sense either: unlike a for loop where you can set up the initial state of the "looping variable", in a while loop you test the value of an existing variable, akin to the conditional check of the for loop.

Of course, if you're concerned about variables "leaking" into other parts of your code, you could enclose the whole thing in an extra scope block:

{
   /*declare variable here*/
   while(...){...}
}

Alternatively, convert the while loop into a for loop.

2 Comments

I think is better & cleaner than the accepted answer. Far more readable.
@rpax While it might be cleaner, I just see it as workaround for my question. I knew of course that I can artificially restrict the scope of a variable with curly braces, but that was not what I asked for. The other answer dwelled more on the alternative solution with for which actually can substitute a while loop.
1

Make a do/while:

String value;
do {
    value = getValue();
    ...your processing
} while (value != null && !value.isEmpty());

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.