1. Overview

In this tutorial, we’ll talk about the Java specification that states that the compiler should raise an error if any statement is unreachable. An unreachable statement is a code that can never be executed during the program execution because there is no way for the program flow to reach it. We’ll see various code examples that correspond to this definition.

2. Code After break Instruction in a Loop

In a loop, if we put instructions after a break statement, they’re not reachable:

public class UnreachableStatement {
    
    public static void main(String[] args) {
        for (int i=0; i<10; i++) {
            break;
            int j = 0;
        }
    }

}

Let’s try to compile our code with javac:

$ javac UnreachableStatement.java
UnreachableStatement.java:9: error: unreachable statement
            int j = 0;
                ^
1 error

As expected, the compilation failed because the int j = 0; statement isn’t reachable. Similarly, an instruction after the continue keyword in a loop isn’t reachable:

public static void main(String[] args) {
    int i = 0;
    while (i<5) {
        i++;
        continue;
        int j = 0;
    }
}

3. Code After a while(true)

A while(true) instruction means the code within runs forever. Thus, any code after that isn’t reachable:

public static void main(String[] args) {
    while (true) {}
    int j = 0;
}

Once again, the statement int j = 0; isn’t reachable in the previous code. This remark is also valid for the equivalent code using the do-while structure:

public static void main(String[] args) {
    do {} while (true);
    int j = 0;
}

On the other hand, any code inside a while(false) loop isn’t reachable:

public static void main(String[] args) {
    while (false) {
        int j = 0;
    }
}

4. Code After Method Returns

A method immediately exits on a return statement. Hence, any code after this instruction isn’t reachable:

public static void main(String[] args) {
    return;
    int i = 0;
}

Once more, the int j = 0; line isn’t reachable, provoking a compiler error. Similarly, when a throw statement isn’t enclosed within a try-catch block or specified in the throws clause, the method completes exceptionally. Thus, any code after this line isn’t reachable:

public static void main(String[] args) throws Exception {
    throw new Exception();
    int i = 0;
}

To recap, if all code branches return, the following code isn’t reachable by any means:

public static void main(String[] args) throws Exception {
    int i = new Random().nextInt(0, 10);
    if (i > 5) {
        return;
    } else {
        throw new Exception();
    }
    int j = 0;
}

In this code, we chose a random number between 0 (inclusive) and 10 (exclusive). If this number is greater than 5, we return immediately, and if not, we throw a generic Exception. Thus, there is no possible execution path for the code after the if-else block.

5. Dead but Reachable Code

Lastly, let’s notice that even obvious dead code isn’t mandatorily unreachable from the compiler’s perspective. In particular, it doesn’t evaluate the conditions inside an if statement:

public static void main(String[] args) {
    if (false) {
        return;
    }
}

This code compiles successfully even if we know at first glance that the code inside the if block is dead code.

6. Conclusion

In this article, we looked at many unreachable statements. There is an argument in the developer community about whether unreachable code should raise a warning or an error. The Java language follows the principle that every written code should have a purpose, thus raising an error. In other languages like C++, as the compiler can execute the code in spite of its incoherencies, it only raises a warning.

Course – LS (cat=Java)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.