59

Why is this code not giving an "unreachable code" error? Since a boolean can only be true or false.

public static void main(String args[]) {
    boolean a = false;
    if (a == true) {

    } else if (a == false) {

    } else {
        int c = 0;
        c = c + 1;
    }
}
Raedwald
  • 46,613
  • 43
  • 151
  • 237
vvill
  • 1,100
  • 2
  • 12
  • 21
  • 1
    See the second half of this question: http://stackoverflow.com/questions/9276378/unreachable-code-compiler-error – azurefrog Mar 18 '16 at 14:10
  • 1
    Also interesting: http://stackoverflow.com/questions/20299914/iffalse-vs-whilefalse-unreachable-code-vs-dead-code – Tom Mar 18 '16 at 14:11
  • 9
    A check in the JLS gives the answer (as always): *"The else-statement is reachable iff the if-then-else statement is reachable. "*. Since both `if` and `else if` are reachable, the `else` statement is it as well. – Tom Mar 18 '16 at 14:14
  • 1
    Refer this http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21 – Parth Soni Mar 18 '16 at 14:15
  • @Tom This should be the answer :) – Yassin Hajaj Mar 18 '16 at 14:16
  • can't boolean values be set to `null`? – Kidiskidvogingogin Mar 18 '16 at 14:20
  • 4
    @Kidiskidvogingogin no, you confuse with `Boolean` which is object. `boolean` is primitive. – Alex Salauyou Mar 18 '16 at 14:22
  • 1
    There are loads of examples of code that is not unreachable but can never be reached - e.g. `default` cases in switches where all possibilities already covered. Why should `boolean` be special just because there are only 2 values? – Paul Boddington Mar 18 '16 at 14:24
  • 2
    it is possible in multithreaded environment that first it is false when it just reaches else if variable is again true – Ehsan Sajjad Mar 18 '16 at 18:53
  • `if (a == true)`, `if (a == false)` <-- Don't ever do this when `a` is a `boolean`. Just do `if (a)` and `if (!a)`. – jpmc26 Mar 18 '16 at 21:06
  • @jpmc26 I am 99% sure both generate the same bytecode. Use what is more readable in the context you need it in. – AlexR Mar 18 '16 at 22:51
  • @AlexR It is a matter of style and presentation. Seeing the code, `a == true` without there being a *very* good reason why screams that the author lacks understanding about what `==` does. I admit that there are rare cases where it might make sense, but these are *extremely* rare. (They might be a bit more common in weakly or dynamically typed languages, but this is Java.) Certainly, in this example, it's completely unnecessary. – jpmc26 Mar 18 '16 at 22:53
  • @jpmc26 I'm not opposed to your general statement, just to the "ever" part of it ;-) – AlexR Mar 18 '16 at 22:55
  • @AlexR To be fair, my comment includes the `if` and the parentheses and that `a ` is a `boolean` (primitive). It *never* makes sense in the full context (a single boolean check on a non-nullable type). – jpmc26 Mar 18 '16 at 22:56
  • This might help: http://thedailywtf.com/articles/What_Is_Truth_0x3f_ – Jeff Olson Mar 22 '16 at 18:59

1 Answers1

59

From JLS 14.21. Unreachable Statements

It is a compile-time error if a statement cannot be executed because it is unreachable.

and

The else-statement is reachable iff the if-then-else statement is reachable.

Your if-then-else statement is reachable. So, by the definition the compiler thinks that the else-statement is reachable.

Note: Interestingly the following code also compiles

// This is ok
if (false) { /* do something */ }

This is not true for while

// This will not compile
while (false) { /* do something */ }

because the reachability definition for while is different (emphasis mine):

The contained statement is reachable iff the while statement is reachable and the condition expression is not a constant expression whose value is false.

dejvuth
  • 6,986
  • 3
  • 33
  • 36
  • 5
    I don't know if this is what the Java designers had in mind, but it can be useful to have `if (COMPILE TIME CONSTANT EXPRESSION) { ... }` constructs where the COMPILE TIME CONSTANT EXPRESSION might be either true or false depending on the environment. – zwol Mar 18 '16 at 20:30
  • @zwol that's exactly the reason why such behavior exists. I also think to remember that in the very first version of JVM `if(false)` was not compilable because clearly unreachable. Also note that this behavior comes in handy to put `if(true){return;}` in the middle of a method while developing for debug purpose. Compiler perfectly knows that everything that comes after is unreachable, but it still allows you to write it since it's just useful to have it. – Jack May 03 '21 at 08:12