Greg
Greg

Reputation: 444

(Compiler) else if(true) vs else scenario

Take the following Java code snippet:

....
    else if (true){ //hard-coded as true
     ///launch methodA
    }
    else {
     ///launch methodA (same code as in the ` else if ` statement)
    }
....

What I was wondering is how the compiler deals with this. Wouldn't it be logical for the compiler to remove the else if(true) statement altogether in order to not have to perform a check, even though it is hard-coded as true. Specifically in Eclipse, how is the code above interpreted?

Or what about in the following scenario:

....
    else if (true){ //hard-coded as true
     ///launch methodA
    }
    else {
     ///launch methodBB
    }
....

Wouldn't it be logical in this case for the compiler to remove the else statement? Because while running, the else statement is unreachable.

Upvotes: 22

Views: 2670

Answers (8)

tarikfasun
tarikfasun

Reputation: 324

Now I write codes in eclipse, my method is

public static void aa(String b) {
  if (true) {

  } else if (true) {
    System.out.println("asas");
  } else {
  }
}

After I compiled my code and I decompile my code with JD-GUI. My decompiled code is:

public static void aa(String b) {}

result is very good!

Upvotes: 2

Related answers: Java If(false) Compile

See especially remarks about using javap -c to diagnose bytecode to see whether dead code was in fact eliminated. https://stackoverflow.com/a/6240017/679457

Upvotes: 0

user207421
user207421

Reputation: 310915

Wouldn't it be logical for the compiler to remove the else if(true) statement altogether in order to not have to perform a check, even though it is hard-coded as true.

No, it wouldn't, unless both blocks had the same content, and why would it check for that? It would be semantically incorrect. What would be logical would be for the compiler to remove the final unreachable else, and that is what it does.

Upvotes: 1

dotvav
dotvav

Reputation: 2848

Unreachable statements are forbidden in Java and must trigger compilation errors. The JLS defines what is an unreachable statements: https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21

It is too long to be entirely quoted here, but here is an extract (emphasis mine):

if (false) { x=3; }

does not result in a compile-time error. An optimizing compiler may realize that the statement x=3; will never be executed and may choose to omit the code for that statement from the generated class file, but the statement x=3; is not regarded as "unreachable" in the technical sense specified here.

The rationale for this differing treatment is to allow programmers to define "flag variables" such as:

static final boolean DEBUG = false;

and then write code such as:

if (DEBUG) { x=3; }

The idea is that it should be possible to change the value of DEBUG from false to true or from true to false and then compile the code correctly with no other changes to the program text.

So the answer will depend on the compiler you use and its optimization options.

Upvotes: 21

Jean Logeart
Jean Logeart

Reputation: 53829

The compiler optmizes it at compile time:

public class Test {
    public static void main(String[] args) {
    if(true) {
        System.out.println("Hello");
    } else {
        System.out.println("Boom");
    }
}

Gives me (with my Java 1.8.0_45):

Compiled from "Test.java"
public class Test {
  publicTest();
    Code:
       0: aload_0
       1: invokespecial #1        // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2        // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3        // String Hello
       5: invokevirtual #4        // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

The code just prints Hello. Boom is not even considered.

All recent Java compilers eliminate dead code at compile time.

Upvotes: 10

uoyilmaz
uoyilmaz

Reputation: 3105

You can try writing the code and decompiling the class file. My compiler optimizes

else if (true){ //hard-coded as true
 ///launch methodA
}
else {
 ///launch methodA (same code as in the else if statement)
}

as

else {
 ///launch methodA
}

and

else if (true){ //hard-coded as true
 ///launch methodA
}
else {
 ///launch methodBB
}

as

else {
 ///launch methodA
}

I think all compiler versions will optimize it in this way.

Upvotes: 3

M. Reif
M. Reif

Reputation: 866

There is no particular answer to this question. It depends on the Java Compiler. Most compilers ignore Dead Code because it will not change the semantic of the code even if it results in a larger class file.

If you are interested in such analysis there is a lot of literature about Dead Code elimination.

Upvotes: 3

dtortola
dtortola

Reputation: 798

About Eclipse in particular, it's going to warn you the last else block is unreachable, but compilation is delegated to your jdk, so maybe it is the compiler what warns Eclipse.

Upvotes: 2

Related Questions