The for loop is Java's workhorse for any task with a known iteration count. Counting through cart items, scanning a list of product ratings, generating order numbers, the for loop handles all of it with one compact piece of syntax. This lesson covers the classic counted form, how each part is evaluated, and the small mistakes that come up most often.
A for loop has three parts inside the parentheses, separated by semicolons, followed by a body in braces.
The three parts are:
| Part | Name | Purpose |
|---|---|---|
int orderNumber = 1 | Initialization | Runs once, before anything else. Usually declares a counter. |
orderNumber <= 5 | Condition | Checked before each iteration. If true, the body runs. If false, the loop ends. |
orderNumber++ | Update | Runs after the body, before the next condition check. Usually advances the counter. |
The order of evaluation matters. On the first pass, Java runs the initialization, checks the condition, runs the body, runs the update, then checks the condition again. From the second pass onward, it's just condition, body, update, repeat.
An important detail: the condition is checked before the body, not after. If the condition is false on the very first check, the body never runs at all. This means a for loop is safe to use when the count might be zero.
Counting from 0 to length - 1 is a common loop shape in Java because it lines up with how arrays are indexed. A small int[] shows the pattern.
Java arrays are zero-indexed, so the first item lives at index 0 and the last lives at index length - 1. The condition uses <, not <=. If you wrote i <= prices.length, the loop would try to read prices[5], which doesn't exist, and Java would throw ArrayIndexOutOfBoundsException.
The name i is fine here. It's the universally recognized convention for a loop index, and using it for that role keeps your code readable. Use a descriptive name when the counter represents something meaningful in the domain, like orderNumber or attemptCount.
The update part doesn't have to be i++. It can be any expression that moves the counter, including decrement, addition, multiplication, or anything else.
Counting down is just as easy as counting up. Flip the starting value, flip the condition, and use -- instead of ++.
You can also step by more than one. A loop that prints every other rating value from 1 to 10:
The update rating = rating + 2 could also be written as rating += 2. Both do the same thing.
The update runs once per iteration. If you put something expensive in there (a method call, a string concatenation), that cost multiplies by the number of iterations. Prefer to keep the update to a simple arithmetic step.
Both the initialization and the update sections accept a comma-separated list. You can declare more than one counter and advance more than one at a time. The condition stays a single boolean expression.
The classic use case is walking from both ends of a structure toward the middle.
left starts at 0 and right starts at the last valid index. Each pass moves them toward each other. When they meet or cross, the condition becomes false and the loop ends.
A few rules to remember about multi-variable for loops:
int i = 0, double price = 0.0.&& or ||.i++, j-- is fine. i + 1, j - 1 is not, because those aren't statements.Multi-variable loops are powerful but easy to overuse. If the loop starts to need three or four counters, it's usually a sign the logic belongs inside the body instead.
A variable declared in the init part of a for loop is local to that loop. It does not exist after the loop ends. The compiler enforces this.
If you uncomment the line that prints itemIndex after the loop, the file won't compile. The compiler reports cannot find symbol: variable itemIndex because the name only exists inside the loop's block.
This is usually what you want. It keeps loop counters from leaking into surrounding code and accidentally being reused. If you do need the final value of the counter after the loop ends, declare the variable outside the loop instead.
lastIndex ends up at 3, not 2. The update happens after the last iteration that runs the body, and the loop only exits once the condition is false. The variable holds the first value that failed the condition.
A common bug in any counted loop is being off by one: starting at the wrong index, stopping one step too early, or stopping one step too late. The two usual suspects are the choice between < and <=, and whether to start at 0 or 1.
What's wrong with this code?
The condition uses <= instead of <. prices.length is 4, but the valid indices are 0, 1, 2, 3. When i reaches 4, the code tries to read prices[4], which doesn't exist, and Java throws ArrayIndexOutOfBoundsException.
Fix:
The rule of thumb: when iterating over a structure with N elements, use i = 0; i < N; i++. The < is intentional because indices run from 0 to N - 1, and there are exactly N of them.
The other off-by-one is starting at the wrong index.
What's wrong with this code?
This loop starts at i = 1, skipping the first element. The total only includes 8 + 12 + 3 = 23, missing the initial 5. The arithmetic looks right but the answer is wrong, which makes this kind of bug hard to spot.
Fix:
There are valid reasons to start at 1 (for example, comparing each item to its previous neighbor), but they should be deliberate, not accidental. When in doubt, start at 0.
All three parts of a for loop are optional. Leave them out and you get the infinite loop, written as for (;;). The semicolons are required because the parser uses them to separate the three sections, even when they're empty.
With no condition to check, the loop will run forever unless something inside the body exits it. The usual escape hatches are break (jumps out of the loop), return (exits the entire method), or throwing an exception. Without one of those, you've created an infinite loop, which will hang your program until you kill it manually.
for (;;) is uncommon in everyday Java. The more common way to write an intentional infinite loop is while (true). The for (;;) form still shows up in older code and some system-level libraries.
10 quizzes