简体   繁体   中英

System.exit and finally code analysis

Please help me to understand the below code,

CASE 1:

finally{
    return;
    System.exit(1);
}

The above code throws compile time error:

Unreachable code

CASE 2:

finally{
    System.exit(1);
    return;
}

The above code doesn't throw any compile/runtime error but when I run the program just exits.

My question here is why the designers thought to throw a compile time error in case 1 where as in case 2 they didn't. Practically when you call System.exit(0) the program will terminate which means the code below it are not reachable.

return is a language feature which the compiler knows about. System.exit(1) is seen by the compiler as a static method invocation, similar to System.out.println(...) . The compiler has no idea what invoking this method actually does.

case 1:

  finally{
        return;
        System.exit(1);
    }

this is unreachable because compiler can see you are returning from the method , so no further code will run.

case 2:

finally{
    System.exit(1);
    return;
}

The above code doesn't throw any compile/runtime error but when I run the program just exits

the docs for exit() answer this one :

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination

and the only exception exit() throws is SecurityException

In Case 1 you are using a language construct to exit a block, any code after would never be run, hence the compiler error.

In Case 2 you are calling a method that forces the JVM to exit not executing any code, so no compiler error there.

For compiler there is no difference between System.out.println() and System.exit() - both are just methods. Compiler doesn't analize it's contents.

The compiler doesn't check what a method does. The simple design decision made by compiler designers was - any line of code that comes after a return statement (in the same block) is unreachable .

It doesn't matter whether you call System.exit() or explodeMyPC() (which might actually Kaboom your PC).

In the first case you are returning from the block before you are calling System.exit, this means System.exit can never be reached.

This is an error that the compiler can identify.

The compiler does not have any idea about how System.exit behaves

Adding flow analysis based on specific library calls would be slow and brittle.

Analysis like this is better left to static analysis tools.

This is a runtime vs compile time distinction. In the first case, the Java Compiler prevents successful compilation because the statement System.exit(1) can never be executed (look at it like this: if the return statement is executed, then there is no way to execute any other statement in the same method. For this reason, the Java specification outlawed this kind of code and, the compiler simply prohibits this code. The return language feature is known to the compiler, which enforces the expectation of no further code. However, System.exit(1) is considered a method call like any other API method.

In the second case, the compiler does not treat System.exit() the way it treats return; statements, which is why the effect of the statement is only left to the runtime. When this code is executing at runtime, the System.exit(1); line is hit and the VM exits, leaving no chance to ever reach the return statement. However, the compiler considers that to be perfectly legal code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM