Is there a keyword "noreturn" in Java?

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

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

But the compiler insists on returning the int value after calling error (), because it does not know that error () will never return. I can, of course, return an arbitrary int, but if the return type is a complex class, I need to build it in the code, which is a waste of time. Is there a way to tell the compiler that the function will never return?

+4
source share
7 answers

You should throw a RuntimeException .

+5
source

There is no way in the Java method signature so that you can tell the compiler that the method cannot return. Without this, the compiler is unable, except to assume that it can return. (Indeed, the JLS reachability / specific purpose rules will state this explicitly ... if you want to get through them.)

I hesitate between two approaches:

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

and

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

None of them are completely satisfactory.

In the first version, the comment is very important, because someone who first read your code may not understand that error never returns.

The second version is more reliable, as it will give you a β€œquick crash” if someone changes the behavior of the error method so that it really returns. (The first version will cause the fun method to return a dummy value ... possibly leading to other unforeseen consequences.)


At a connected point, a method that pulls out a JVM fork by calling System.exit() can be problematic. The best idea is to throw the end of the world exception and catch it at the extreme level of your main thread. For exceptions superimposed on other threads, one idea would be to install a default exception exception handler that uses Thread.interrupt() to notify the main thread that an β€œend of the world” exception has been thrown.

But the fact is that System.exit() calls made deep in the code are problematic; for example, if you reprogram your code to work in a larger structure; for example in a web container.

+5
source

Java does not allow you to declare that your method never returns, but the compiler knows a statement that never returns: throw .

You can use this in your situation by declaring your method "no return" to RuntimeException and call it with throw error() . Thus, you transfer the problem of the "method that does not return" to the "operator that does not return".

Since your error() method never returns, you do not need to actually return a declared RuntimeException , and throw in throw error() never executed.

This method can also prevent you from errors when returning error() , possibly due to some conditional code with an error.

Example:

 private RuntimeException error() { throw new EndOfTheWorldException(); // Java knows that code after throw will not be reached // so no return is required here. Or, if you insist, you // could call System.exit() and return null afterwards. } int fun() { // ... throw error(); // Again, no need for a return here, the compiler understands // that the statement above won't return. } 

Alternatively and perhaps more explicitly, you can reorganize this code to make error() a factory to exclude:

 private RuntimeException makeError() { return new EndOfTheWorldException(); } int fun() { throw makeError(); } 
+3
source

returns 0 or in complex cases returns null.

+2
source

Not sure why you want to do this. This would be cleaner code, more verifiable and maintainable, if you would choose an exception; you can use Thread.setDefaultUncaughtExceptionHandler() to exit.

But if you insist:

 public class HaltAndCatchFireError extends Error { public HaltAndCatchFireError() { System.exit(1); } } 

And then where you want to exit:

 int fun() { ... throw new HaltAndCatchFireError(); } 
+1
source

Does your function return anything? If you do not want your function to be invalid, it seems:

 void fun() { ... } 
0
source

You can write

 error(); return; 

But you can reconsider your approach. It may not be very object oriented.

-2
source

Source: https://habr.com/ru/post/1347179/


All Articles