Java for Loop
Java for Loop
The for loop executes a block of code a specific number of times. When you know the iteration count upfront — the size of an array, the number of items to process, a fixed retry count — the for loop is the correct choice. It keeps the initialization, condition, and update all in one line, making the loop's intent immediately visible.
What separates solid for loop usage from beginner mistakes is understanding the three-part header and the precise moment each part executes. That timing is what causes off-by-one errors, infinite loops, and unexpected variable scope — all of which appear regularly in code reviews.
What Is the Java for Loop?
The for loop is a control flow statement that repeats a block of code while a condition is true, incrementing or decrementing a counter variable on each pass. The three parts of the loop header — initialization, condition, and update — are all declared in one line, which is the clearest signal to any developer reading the code that this loop runs for a known, bounded number of iterations.
Java provides three forms of the for loop:
- ›Basic
forloop — when you need the index or a precise iteration count - ›Enhanced
forloop (for-each) — when you need each element but not the index - ›Infinite
forloop — when the loop's exit is controlled by internal logic, not a counter
Syntax
Basic for Loop
1for (initialization; condition; update) {
2 // loop body — runs while condition is true
3}The three parts in the header:
- ›Initialization — runs once before the first iteration
- ›Condition — checked before each iteration; loop stops when false
- ›Update — runs after each iteration, before the condition is re-checked
Enhanced for Loop (for-each)
1for (ElementType element : collection) {
2 // element holds the current value on each pass
3}The enhanced for loop, introduced in Java 5, iterates over arrays and any class that implements Iterable. It has no index variable and does not expose the current position — which makes it cleaner when you only need the values.
Infinite for Loop
1for (;;) {
2 // runs forever unless break or return exits it
3}All three parts are optional. Omitting the condition makes it permanently true. This pattern appears in server polling loops, retry mechanisms, and event processing systems where the exit condition is determined by runtime state, not a counter.
Beginner Examples
Basic for Loop — Iterating a Known Count
This shows the most common use case: processing a fixed range of values.
1public class BatchSummaryDemo {
2
3 public static void main(String[] args) {
4
5 int totalOrders = 5;
6 double totalRevenue = 0.0;
7
8 // Loop runs from 1 through totalOrders inclusive
9 // index represents the order number in this batch
10 for (int index = 1; index <= totalOrders; index++) {
11 double orderValue = index * 120.0; // simulated order value
12 totalRevenue += orderValue;
13 System.out.println("Order #" + index + " processed. Value: Rs. " + orderValue);
14 }
15
16 System.out.println("Batch complete. Total revenue: Rs. " + totalRevenue);
17 }
18}Output:
Order #1 processed. Value: Rs. 120.0
Order #2 processed. Value: Rs. 240.0
Order #3 processed. Value: Rs. 360.0
Order #4 processed. Value: Rs. 480.0
Order #5 processed. Value: Rs. 600.0
Batch complete. Total revenue: Rs. 1800.0
The loop variable index is declared inside the for header — it exists only within the loop block and the header itself. Once the loop exits, index is gone. This scoping is intentional: it prevents the loop counter from accidentally being used outside the loop where its value is no longer meaningful.
Enhanced for Loop — Iterating a Collection
When you need every element but do not need to track position, the enhanced form is cleaner and less error-prone than the basic form.
1import java.util.List;
2
3public class ProductListDemo {
4
5 public static void main(String[] args) {
6
7 List<String> productNames = List.of("Laptop", "Mouse", "Keyboard", "Monitor", "Webcam");
8
9 double taxRate = 0.18;
10
11 for (String productName : productNames) {
12 // No index management — the JVM handles iteration internally
13 System.out.println("Product: " + productName
14 + " | Tax category: " + (taxRate * 100) + "%");
15 }
16 }
17}Output:
Product: Laptop | Tax category: 18.0%
Product: Mouse | Tax category: 18.0%
Product: Keyboard | Tax category: 18.0%
Product: Monitor | Tax category: 18.0%
Product: Webcam | Tax category: 18.0%
The enhanced for loop cannot be used when you need to modify the list while iterating, remove elements, or access adjacent elements by index. For any of those requirements, the basic for with explicit indexing is necessary.
Reverse Iteration
The for loop is equally natural for iterating backwards — common in search algorithms, undo stacks, and display logic.
1public class ReverseRankDemo {
2
3 public static void main(String[] args) {
4
5 String[] topSellers = {"Priya Sharma", "Rahul Verma", "Ananya Nair", "Vikram Singh", "Deepa Reddy"};
6
7 System.out.println("Leaderboard (highest to lowest rank):");
8
9 // Starting at the last index and decrementing to zero
10 for (int position = topSellers.length - 1; position >= 0; position--) {
11 System.out.println("Rank " + (topSellers.length - position) + ": " + topSellers[position]);
12 }
13 }
14}Output:
Leaderboard (highest to lowest rank):
Rank 1: Deepa Reddy
Rank 2: Vikram Singh
Rank 3: Ananya Nair
Rank 4: Rahul Verma
Rank 5: Priya Sharma
Starting at topSellers.length - 1 instead of topSellers.length is the correct initialization for a zero-indexed array. Starting at length without subtracting 1 would cause an ArrayIndexOutOfBoundsException on the very first access — one of the most common off-by-one mistakes in Java.
How the Java for Loop Works Internally
Execution Sequence
Every iteration of a for loop follows a precise four-step sequence. Understanding this order is what prevents timing-related bugs.
Start
|
Initialization
(runs exactly once)
|
+-----------+
| |
Condition Condition
is true is false
| |
Execute body Exit loop
|
Update
(runs after body)
|
Re-check condition
The initialization runs once. The condition is checked before each iteration — including the first. The update runs after the body — the body executes first, then the update, then the condition is re-checked. This sequence matters when the update expression has side effects.
The Loop Variable Lives in Header Scope
The variable declared in the for header has a scope that includes the header itself and the loop body. It does not exist before the for statement or after it exits.
1for (int counter = 0; counter < 3; counter++) {
2 System.out.println(counter);
3}
4// counter is not accessible here — scope ended when the loop exitedThis scope design prevents a common class of bugs where a loop variable is accidentally read after the loop has run, when its value is meaningless.
Enhanced for Loop — Internal Iterator
The enhanced for loop is syntactic sugar. For any class implementing Iterable, the compiler transforms it into an Iterator-based loop. For arrays, the compiler transforms it into a basic indexed for loop internally. You never interact with the iterator directly, but knowing it exists explains why removing elements from a List inside an enhanced for loop throws a ConcurrentModificationException.
Real-World Example — Bulk Report Generator for an Ed-Tech Platform
The Business Problem
You are building the performance report generation service for an Indian ed-tech company — similar to what Vedantu or Physics Wallah runs for its batch report system. At the end of each monthly assessment cycle, the system must iterate through all student records in a batch, calculate their performance tier based on their score, and generate a formatted report line for each.
The report covers a known, fixed set of students — the batch size is determined before the loop starts. The for loop is the natural fit: bounded, index-accessible, and clean when the count is known at runtime.
Implementation
1// File: StudentRecord.java
2
3public class StudentRecord {
4
5 private final String studentName;
6 private final int assessmentScore;
7 private final String batchCode;
8
9 public StudentRecord(String studentName, int assessmentScore, String batchCode) {
10 this.studentName = studentName;
11 this.assessmentScore = assessmentScore;
12 this.batchCode = batchCode;
13 }
14
15 public String getStudentName() { return studentName; }
16 public int getAssessmentScore() { return assessmentScore; }
17 public String getBatchCode() { return batchCode; }
18}1// File: ReportConfig.java
2
3public final class ReportConfig {
4
5 public static final int DISTINCTION_THRESHOLD = 85;
6 public static final int PASS_THRESHOLD = 50;
7
8 private ReportConfig() {}
9}1// File: BatchReportGenerator.java
2
3public class BatchReportGenerator {
4
5 public void generateReport(StudentRecord[] studentRecords) {
6
7 System.out.println("=== Monthly Assessment Report ===");
8 System.out.println("Batch: " + (studentRecords.length > 0
9 ? studentRecords[0].getBatchCode() : "N/A"));
10 System.out.println("Total Students: " + studentRecords.length);
11 System.out.println("-----------------------------------");
12
13 int distinctionCount = 0;
14 int passCount = 0;
15 int failCount = 0;
16
17 // Iterate all students — index gives the sequential report number
18 for (int studentIndex = 0; studentIndex < studentRecords.length; studentIndex++) {
19
20 StudentRecord record = studentRecords[studentIndex];
21 int score = record.getAssessmentScore();
22 String tier;
23
24 if (score >= ReportConfig.DISTINCTION_THRESHOLD) {
25 tier = "Distinction";
26 distinctionCount++;
27 } else if (score >= ReportConfig.PASS_THRESHOLD) {
28 tier = "Pass";
29 passCount++;
30 } else {
31 tier = "Fail";
32 failCount++;
33 }
34
35 System.out.printf("%d. %-20s | Score: %3d | Result: %s%n",
36 studentIndex + 1,
37 record.getStudentName(),
38 score,
39 tier);
40 }
41
42 System.out.println("-----------------------------------");
43 System.out.println("Distinction: " + distinctionCount
44 + " | Pass: " + passCount
45 + " | Fail: " + failCount);
46 }
47}1// File: ReportDemo.java
2
3public class ReportDemo {
4
5 public static void main(String[] args) {
6
7 StudentRecord[] batch = {
8 new StudentRecord("Arjun Mehta", 92, "JEE-2024-A"),
9 new StudentRecord("Priya Iyer", 78, "JEE-2024-A"),
10 new StudentRecord("Rahul Singh", 55, "JEE-2024-A"),
11 new StudentRecord("Sneha Kapoor", 88, "JEE-2024-A"),
12 new StudentRecord("Karan Patel", 41, "JEE-2024-A")
13 };
14
15 BatchReportGenerator generator = new BatchReportGenerator();
16 generator.generateReport(batch);
17 }
18}Output:
=== Monthly Assessment Report ===
Batch: JEE-2024-A
Total Students: 5
-----------------------------------
1. Arjun Mehta | Score: 92 | Result: Distinction
2. Priya Iyer | Score: 78 | Result: Pass
3. Rahul Singh | Score: 55 | Result: Pass
4. Sneha Kapoor | Score: 88 | Result: Distinction
5. Karan Patel | Score: 41 | Result: Fail
-----------------------------------
Distinction: 2 | Pass: 2 | Fail: 1
The basic for loop with explicit indexing is used here — not the enhanced form — because the report number studentIndex + 1 is needed to label each line. The enhanced for would clean up the body slightly but would lose access to the sequential position number.
The thresholds are in ReportConfig as constants. When the institution changes the distinction cutoff from 85 to 90, only one line in one file changes. A mistake that appears often in fresher pull requests is hardcoding values like 85 and 50 directly inside loop bodies — those values then appear in multiple places and require scattered edits when requirements change.
Best Practices
Use the enhanced for loop when you do not need the index
The enhanced form is shorter, removes index management entirely, and eliminates the off-by-one class of bugs. Default to it when iterating collections and arrays unless the position genuinely matters to the logic.
1// Prefer this when you only need each value
2for (String item : itemList) {
3 process(item);
4}
5
6// Use this only when position matters
7for (int i = 0; i < itemList.size(); i++) {
8 processWithPosition(i, itemList.get(i));
9}Declare the loop variable inside the for header
Declaring the loop variable before the for statement unnecessarily widens its scope and leaves it accessible after the loop exits with a value that no longer means anything useful. IntelliJ IDEA and SonarQube both flag this as a code quality issue.
Keep the loop body focused on one responsibility
When a loop body grows beyond eight to ten lines, consider extracting it into a method. A loop that iterates students, calculates grades, formats output, and updates a database in a single body is doing too much. Extraction makes each concern testable independently.
Avoid modifying the collection inside an enhanced for loop
Removing or adding elements to a List while iterating it with the enhanced for throws ConcurrentModificationException. If modification during iteration is required, use an explicit Iterator with iterator.remove(), or iterate a copy while modifying the original.
Common Mistakes
Mistake 1 — Off-by-One Error in the Loop Condition
Off-by-one errors are the most common bug in basic for loops. The boundary condition — < versus <= — determines whether the last element is processed or skipped.
1public class OffByOneDemo {
2
3 public static void main(String[] args) {
4
5 int[] scores = {88, 72, 95, 61, 79};
6
7 System.out.println("--- Using < scores.length (correct) ---");
8 for (int i = 0; i < scores.length; i++) {
9 System.out.println("Score at index " + i + ": " + scores[i]);
10 }
11
12 System.out.println("\n--- Using <= scores.length (causes ArrayIndexOutOfBoundsException) ---");
13 try {
14 for (int i = 0; i <= scores.length; i++) {
15 // When i equals scores.length, scores[i] is out of bounds
16 System.out.println("Score at index " + i + ": " + scores[i]);
17 }
18 } catch (ArrayIndexOutOfBoundsException ex) {
19 System.out.println("Exception at index " + scores.length + ": " + ex.getMessage());
20 }
21 }
22}Output:
--- Using < scores.length (correct) ---
Score at index 0: 88
Score at index 1: 72
Score at index 2: 95
Score at index 3: 61
Score at index 4: 79
--- Using <= scores.length (causes ArrayIndexOutOfBoundsException) ---
Score at index 0: 88
Score at index 1: 72
Score at index 2: 95
Score at index 3: 61
Score at index 4: 79
Exception at index 5: Index 5 out of bounds for length 5
Java arrays are zero-indexed. The valid index range for an array of length 5 is 0 through 4. Using <= scores.length attempts to access index 5, which does not exist. The rule is always < array.length for forward iteration over a zero-indexed array.
Mistake 2 — Infinite Loop from Wrong Update Expression
1// Update is incrementing the wrong variable — this never terminates
2int limit = 10;
3for (int counter = 0; counter < limit; limit++) {
4 // limit grows with each iteration — counter never reaches it
5 System.out.println(counter);
6}Incrementing limit instead of counter means the condition counter < limit is always true — both sides grow but counter stays at 0 while limit increases without bound. During code reviews, three-part for headers where all three parts reference the same variable are flagged immediately.
Mistake 3 — Modifying the Loop Variable Inside the Body
1public class LoopVariableMutationDemo {
2
3 public static void main(String[] args) {
4
5 // Modifying the loop counter inside the body creates unpredictable iteration
6 for (int i = 0; i < 5; i++) {
7 System.out.println("i = " + i);
8 i++; // i increments inside the body AND in the update expression
9 // Effective increment per iteration is 2, not 1
10 }
11 }
12}Output:
i = 0
i = 2
i = 4
The loop only printed three values instead of five because i was incremented twice per iteration — once in the body and once in the update expression. Mutating the loop counter inside the body is consistently flagged in code reviews. If a step size other than 1 is needed, express it in the update expression: i += 2.
Mistake 4 — Using Enhanced for Loop When Modification Is Needed
1import java.util.ArrayList;
2import java.util.List;
3
4public class ModificationMistakeDemo {
5
6 public static void main(String[] args) {
7
8 List<String> pendingOrders = new ArrayList<>();
9 pendingOrders.add("ORD-001");
10 pendingOrders.add("ORD-002");
11 pendingOrders.add("ORD-003");
12
13 try {
14 for (String order : pendingOrders) {
15 if (order.equals("ORD-002")) {
16 // Removing from the list while iterating it throws an exception
17 pendingOrders.remove(order);
18 }
19 }
20 } catch (java.util.ConcurrentModificationException ex) {
21 System.out.println("ConcurrentModificationException: cannot modify list during iteration.");
22 }
23 }
24}Output:
ConcurrentModificationException: cannot modify list during iteration.
The correct approach for removing elements during iteration is to use Iterator with iterator.remove(), or to collect the elements to remove and delete them after the loop completes.
Interview Questions
Q1. What are the three parts of the Java for loop header and when does each execute?
The three parts are initialization, condition, and update. Initialization runs exactly once before the first iteration. The condition is checked before every iteration — if it is false on the first check, the loop body never runs. The update runs after each iteration, before the condition is re-evaluated. This ordering means the body executes before the update expression on each pass, which matters when the update has side effects.
Q2. What is the difference between a basic for loop and an enhanced for loop in Java?
The basic for loop uses an explicit index counter and can iterate in any direction, access elements by position, and modify the collection if using manual index management. The enhanced for loop iterates over every element in a collection or array without exposing an index, is simpler to write, and eliminates off-by-one errors from boundary conditions. The enhanced form cannot be used when you need the current position, need to skip elements, or need to modify the collection during iteration.
Q3. What causes a ConcurrentModificationException in a Java for-each loop?
The enhanced for loop uses an Iterator internally. Most Java collection implementations track a modification count. If the collection is modified directly — by calling add() or remove() on it — while the iterator is active, the iterator detects the change and throws ConcurrentModificationException as a safety mechanism to prevent inconsistent iteration state. The fix is to use Iterator.remove() for safe removal during iteration, or to collect items to modify and apply the changes after the loop completes.
Q4. How does the scope of a variable declared in the for loop header differ from one declared outside it?
A variable declared inside the for header exists only within the header and the loop body. Once the loop exits, that variable is no longer accessible. A variable declared before the for statement exists in the enclosing scope and is still accessible after the loop. Declaring loop counters inside the header is the preferred practice because it prevents the counter from being accidentally read or modified outside the loop where its value is undefined.
Q5. What is the for-each loop internally compiled to in Java?
For classes that implement Iterable, the enhanced for loop is compiled into an iterator-based loop — iterator.hasNext() controls the loop condition and iterator.next() retrieves each element. For arrays, it is compiled into a basic indexed for loop with an index starting at 0 and going to array.length - 1. The JVM never sees for-each directly; it sees the expanded form. This explains why ConcurrentModificationException is possible — the underlying iterator detects external modification.
Q6. When would you choose a while loop over a for loop in Java?
Use a for loop when the iteration count or the starting and ending bounds are known before the loop begins — iterating an array, processing a fixed batch size, or running a known number of retries. Use a while loop when the termination condition depends on runtime state that may change unpredictably — reading lines from a file until end-of-file, waiting for a network response, or polling a queue until it is empty. The general rule: for when you know the count, while when you do not.
FAQs
What is the for loop used for in Java?
The for loop repeats a block of code a specific number of times. Use it when the iteration count is known before the loop starts — processing all items in an array, running a fixed number of retries, or iterating through a list from start to finish. When the count is unknown and depends on runtime conditions, a while loop is more appropriate.
What is the enhanced for loop in Java?
The enhanced for loop, also called the for-each loop, iterates over every element in an array or collection without requiring an explicit index counter. Introduced in Java 5, it is simpler and less error-prone than the basic form when you only need the values and not the positions. It cannot modify the collection during iteration and does not expose the current index.
What happens if the for loop condition is false from the start?
The loop body never executes. The condition is checked before the first iteration — if it is already false, execution continues at the statement after the closing brace of the loop. A loop that never runs is valid Java and produces no error.
Can you have multiple variables in a for loop header in Java?
Yes. You can declare and initialize multiple variables of the same type in the initialization, and include multiple update expressions separated by commas. For example: for (int i = 0, j = 10; i < j; i++, j--). Variables of different types cannot be declared together in the initialization section.
How do you exit a for loop early in Java?
Use break to exit the loop immediately, regardless of whether the condition is still true. Use return inside a method to exit the method entirely, which also terminates the loop. Use continue to skip the rest of the current iteration and immediately move to the update expression. All three are valid and each serves a distinct use case.
What is an infinite for loop in Java?
An infinite for loop is written as for (;;), omitting all three header parts. The condition defaults to true and the loop runs indefinitely. Infinite loops are used in server polling systems, retry mechanisms, and event loops where the exit condition is determined by runtime logic inside the body using break or return.
Can you nest for loops in Java?
Yes. A for loop can contain another for loop in its body. Nested loops are used for two-dimensional array traversal, matrix operations, and generating combinations. The inner loop completes all its iterations for every single iteration of the outer loop. Be aware that nested loops multiply the iteration count — two loops of size N each produce N*N total iterations.
Summary
The for loop is the right choice when the iteration count is known before the loop starts. The three-part header — initialization, condition, update — runs in a precise sequence that determines exactly when each part executes, and understanding that timing is what prevents off-by-one errors and infinite loops.
The enhanced for loop removes index management entirely and is the cleaner choice whenever element position is not needed. When iteration requires modification, or when you need adjacent elements, the basic indexed form gives you that control.
For interviews, know the execution order of the three header parts, be able to explain what causes ConcurrentModificationException in a for-each loop, and be ready to compare for versus while with a concrete decision criterion. Those three points cover the depth that both service-based recall questions and product-based depth questions test on this topic.
What to Read Next
| Topic | Link |
|---|---|
| How the while loop handles iteration when the count is unknown | Java while Loop → |
| How break and continue control early exit and iteration skipping | Java break and continue → |
| How the do-while loop guarantees at least one iteration | Java do-while Loop → |
| How the switch statement handles discrete value matching | Java switch Statement → |
| How Java arrays store and access indexed data | Java Arrays → |