tags:

views:

238

answers:

5

Hi,

What is the difference with or without System.exit(0) in following code?

  1 public class TestExit
  2 {
  3 
  4     public static void main(String[] args)
  5     {
  6 
  7         System.out.println("hello world");
  8     
  9         System.exit(0);  // is it necessary? And when it must be called? 
 10     }
 11 
 12 }

The document says: "This method never returns normally." What does it mean?

+4  A: 

In that case, it's not needed. No extra threads will have been started up, you're not changing the exit code (which defaults to 0) - basically it's pointless.

When the docs say the method never returns normally, it means the subsequent line of code is effectively unreachable, even though the compiler doesn't know that:

System.exit(0);
System.out.println("This line will never be reached");

Either an exception will be thrown, or the VM will terminate before returning. It will never "just return".

It's very rare to be worth calling System.exit() IME. It can make sense if you're writing a command line tool, and you want to indicate an error via the exit code rather than just throwing an exception... but I can't remember the last time I used it in normal production code.

Jon Skeet
Why doesn't the compiler know that? Isn't System.exit() special enough to warrant specific detection code?
Bart van Heukelom
@Bart: No, I don't think so. Putting special cases in the language for things like this adds to language complexity with very little benefit.
Jon Skeet
@Jon, I thought "never returns normally" had to do with "abrupt completion" of the statement. (JLS section 14.1). Am I wrong?
aioobe
@aioobe: No, you're right. `System.exit()` will never complete normally - it will always either complete with an exception, or with the VM shutting down (which isn't really covered in the JLS).
Jon Skeet
+8  A: 

System.exit() can be used to run shutdown hooks before the program quits. This is a convenient way to handle shutdown in bigger programs, where all parts of the program can't (and shouldn't) be aware of each other. Then, if someone wants to quit, he can simply call System.exit(), and the shutdown hooks (if properly set up) take care of doing all necessary shutdown ceremonies such as closing files, releasing resources etc.

"This method never returns normally." means just that the method won't return; once a thread goes there, it won't come back.

Another, maybe more common, way to quit a program is to simply to reach the end of the main method. But then you need some other means (than the shutdown hooks) to shut down all non-daemon threads and release other resources (unless you only have one thread).

For some reason shutdown hooks seem to be an undervalued and misunderstood mechanism, and people are reinventing the wheel with all kind of proprietary custom hacks to quit their programs. I would encourage using shutdown hooks; it's all there in the standard Runtime that you'll be using anyway.

Joonas Pulakka
"This method never returns normally." means just that the method won't return; once a thread goes there, it won't come back. Note in particular that this means you can't unit test a method that makes a System.exit(0) call...
Bill Michell
-1 Incorrect. Shutdown hooks will run if the JVM terminates normally, no matter if it's because of System.exit or termination of main(). See http://zx81/doku/java/javadoc/j2se1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29
sleske
@sleske: Termination of main() is not sufficient if there are other non-daemon threads around. Shutdown is initiated only after the last non-daemon thread has terminated, unless you explicitly call System.exit(). That's clearly stated in the Runtime documentation.
Joonas Pulakka
@Joonas: Before the edit the text might have been read to mean that shutdown hooks run *only* with System.exit. Now it's correct, so I'll take back the vote.
sleske
+3  A: 

System.exit is needed

  • when you want to return a non-0 error code
  • when you want to exit your program from somewhere that isn't main()

In your case, it does the exact same thing as the simple return-from-main.

mfx
What do you mean with the latter? The proper way to shut down the program is stopping all threads (nicely), a move which does not have to be initiated from the main thread, so it's not like `exit` is your only option there.
Bart van Heukelom
@Bart: what you describe is *one of the possible ways* to shut down a program, not *the proper way*. There's nothing wrong in using shutdown hooks to stop all threads nicely. And shutdown hooks are launched with `exit`. Not the only option, but definitely an option worth considering.
Joonas Pulakka
But what I gather from the docs, shutdown hooks are very delicate and may not have a lot of time to do what you want them to do. By all means, use them to quit nicely in case of an OS shutdown or something, but if you're going to call System.exit() yourself I think it's better to do the shutdown code before it (after which you will probably not need System.exit() any more)
Bart van Heukelom
Shutdown hooks do have all the time they take to finish. The VM is not halted before all the hooks have returned. It's indeed possible to prevent the VM from quitting by registering a shutdown hook that takes very long time to execute. But of course it's possible to do the shutdown sequence in various, alternative ways.
Joonas Pulakka
+3  A: 

System.exit(0) terminates the JVM. In simple examples like this it is difficult to percieve the difference. The parameter is passed back to the OS and is normally used to indicate abnormal termination (eg some kind of fatal error), so if you called java from a batch file or shell script you'd be able to get this value and get an idea if the application was successful.

It would make a quite an impact if you called System.exit(0) on an application deployed to an application server (think about it before you try it).

Qwerky
A: 

The method never returns because it's the end of the world and none of your code is going to be waiting.

Your application would exit anyway at the same spot in the code, but you have the option of returning a custom code to the enviroment, like in

System.exit(42);

Who is going to make use of your exit code? A script that called the application. Works in Windows, Unix and all other scriptable environments.

Why return a code? To say things like "I did not succeeed", "The database did not answer".

mico