Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a "noreturn" keyword in Java

Sometimes I want to write a error() function which will surely call System.exit() in the end, meaning that this function will never return. However, if I call error() in other functions, I want to write like:

int fun() {
...
  error();
}

But the compiler insist on returning a int value after the error() call since it don't know that error() will never return. I can surely return a arbitrary int, but if the return type is a complex class, I need to construct it in the code which is a waste of time. Is there any way to tell the compiler that a function will never return?

like image 322
Xiaolong Li Avatar asked Dec 07 '22 22:12

Xiaolong Li


1 Answers

There is no way in a Java method signature that you can tell the compiler that the method cannot return. Without that, the compiler has no option but to assume that it might return. (Indeed, the JLS rules about reachability / definite assignment will state this explicitly ... if you care to wade through them.)

I vacillate between two approaches:

int fun() {
    ...
    error();
    return 0;  // NOT REACHED
}

and

int fun() {
    ...
    error();
    throw new AssertionError("not reached");
}

Neither is entirely satisfactory.

In the first version, the comment is important, since someone reading your code for the first time might not realize that error never returns.

The second version is more robust, since it will give you a "fast fail" if someone changes the behaviour of the error method so that it actually returns. (The first version will result in the the fun method returning a bogus value ... possibly leading to other unintended consequences.)


On a related point, a method that pulls the plug on the JVM by calling System.exit() can be problematic. A better idea is to throw an unchecked "end the world" exception and catch it at the outermost level of your main thread. For exceptions thrown on other threads, one idea would be to install a default uncaught exception handler that uses Thread.interrupt() to notify the main thread that an "end the world" exception has been thrown.

But the point is that System.exit() calls made deep down in the code are problematic; e.g. if you repurpose your code to run within a larger framework; e.g. in a web container.

like image 103
Stephen C Avatar answered Dec 10 '22 13:12

Stephen C