En Java, quelle est la différence avec ou sans System.exit(0)
dans le code suivant?
public class TestExit
{
public static void main(String[] args)
{
System.out.println("hello world");
System.exit(0); // is it necessary? And when it must be called?
}
}
Le document dit: "Cette méthode ne retourne jamais normalement." Qu'est-ce que ça veut dire?
System.exit()
peut être utilisé pour exécuter crochets d'arrêt avant la fermeture du programme. C'est un moyen pratique de gérer les arrêts dans les grands programmes, où toutes les parties du programme ne peuvent pas (et ne devraient pas) être conscientes les unes des autres. Ensuite, si quelqu'un veut quitter, il peut simplement appeler System.exit()
et les crochets d'arrêt (s'ils sont correctement configurés) s'occupent de toutes les cérémonies d'arrêt nécessaires, telles que la fermeture de fichiers, la libération de ressources, etc.
"Cette méthode ne retourne jamais normalement." signifie simplement que la méthode ne reviendra pas; une fois qu'un fil y passe, il ne reviendra pas.
Un autre moyen, peut-être plus courant, de quitter un programme consiste simplement à atteindre la fin de la méthode main
. Mais si des threads non-démon sont en cours d'exécution, ils ne seront pas arrêtés et donc la machine virtuelle Java ne se fermera pas. Ainsi, si vous avez de tels threads non démon, vous avez besoin d'autres moyens (que les crochets d'arrêt) pour arrêter tous les threads non démon et libérer d'autres ressources. S'il n'y a pas d'autres threads non démon, le retour de main
arrêtera la machine virtuelle Java et appellera les points d'ancrage.
Pour certaines raisons, les crochets d'arrêt semblent être un mécanisme sous-estimé et incompris, et les gens réinventent la roue avec toutes sortes de piratages personnalisés pour arrêter leurs programmes. Je vous encourage à utiliser des crochets d'arrêt. tout est là dans le standard Runtime que vous utiliserez quand même.
Dans ce cas, ce n'est pas nécessaire. Aucun thread supplémentaire n'a été démarré, vous ne modifiez pas le code de sortie (dont la valeur par défaut est 0) - en gros, cela ne sert à rien.
Lorsque la documentation dit que la méthode ne retourne jamais normalement, cela signifie que la ligne de code suivante est effectivement inaccessible, même si le compilateur ne sait pas que:
System.exit(0);
System.out.println("This line will never be reached");
Soit une exception sera levée, soit le VM se terminera avant de revenir. Il ne sera jamais "juste revenir".
Il est très rare d’être utile d’appeler System.exit()
IME. Cela peut avoir un sens si vous écrivez un outil en ligne de commande et que vous voulez indiquer une erreur via le code de sortie plutôt que de simplement lancer une exception ... mais je ne me souviens pas de la dernière fois que je l'ai utilisé dans un code de production normal. .
La méthode ne retourne jamais car c'est la fin du monde et aucun de votre code ne sera exécuté ensuite.
Votre application, dans votre exemple, se terminerait quand même au même endroit dans le code, mais si vous utilisez System.exit. vous avez la possibilité de retourner un code personnalisé à l'environnement, comme par exemple
System.exit(42);
Qui va utiliser votre code de sortie? Un script qui appelle l'application. Fonctionne sous Windows, Unix et tous les autres environnements de script.
Pourquoi retourner un code? Pour dire des choses comme "je n'ai pas réussi", "la base de données n'a pas répondu".
Pour voir comment obtenir la valeur od un code de sortie et l'utiliser dans un script Shell unix ou Windows, vous pouvez vérifier cette réponse sur ce site
System.exit(0)
termine la machine virtuelle. Dans des exemples simples comme celui-ci, il est difficile de percevoir la différence. Le paramètre est renvoyé au système d’exploitation et est normalement utilisé pour signaler une fin anormale (erreur fatale, par exemple). Par conséquent, si vous appelez Java à partir d’un fichier de commandes ou d’un script Shell, vous pourrez obtenir cette valeur et avoir une idée si l'application a réussi.
Cela aurait un impact considérable si vous appeliez System.exit(0)
sur une application déployée sur un serveur d'applications (réfléchissez-y avant de l'essayer).
Dans les applications pouvant comporter des points d'arrêt complexes, cette méthode ne doit pas être appelée à partir d'un thread inconnu. System.exit
ne se ferme jamais normalement car l'appel sera bloqué jusqu'à ce que la machine virtuelle Java soit terminée. C'est comme si le code en cours d'exécution était branché avant de pouvoir être terminé. L'appel de System.exit
lancera les crochets d'arrêt du programme et tout fil qui appelle System.exit
sera bloqué jusqu'à la fin du programme. Cela implique que si le crochet d'arrêt soumet à son tour une tâche au thread à partir duquel System.exit
a été appelé, le programme se bloquera.
Je gère cela dans mon code avec les éléments suivants:
public static void exit(final int status) {
new Thread("App-exit") {
@Override
public void run() {
System.exit(status);
}
}.start();
}
On ne devrait JAMAIS appeler System.exit(0)
pour ces raisons:
Quitter le programme "normalement" fournit le même code de sortie au système d'exploitation que System.exit(0)
, de sorte qu'il est redondant.
Si votre programme ne peut pas quitter "normalement", vous avez perdu le contrôle de votre développement [conception]. Vous devriez toujours avoir le plein contrôle de l'état du système.
Soit dit en passant: Il est logique de renvoyer des codes retour autres que 0 si vous souhaitez indiquer une fin de programme anormale.
Bien que la réponse ait été vraiment utile, mais que certains détails manquaient encore. J'espère que ci-dessous aidera à comprendre le processus d'arrêt en Java, en plus de la réponse ci-dessus:
PS: La machine virtuelle Java peut s’arrêter de manière ordonnée ou abrupte.
System.exit est nécessaire
Dans votre cas, il fait exactement la même chose que le simple renvoi du principal.
Spécification du langage Java dit que
Sortie du programme
Un programme termine toute son activité et se termine lorsque l’une des deux choses suivantes se produit:
Tous les threads qui ne sont pas des démons se terminent.
Certains threads appellent la méthode de sortie de la classe Runtime ou de la classe System , et l'opération de sortie n'est pas interdite par le gestionnaire de sécurité.
Cela signifie que vous devriez l'utiliser quand vous avez un gros programme (enfin, au moins plus gros que celui-ci) et que vous voulez terminer son exécution.
Si vous utilisez un autre programme dans la machine virtuelle Java et que vous utilisez System.exit, ce deuxième programme sera également fermé. Imaginons par exemple que vous exécutiez un travail Java sur un nœud de cluster et que le programme Java qui gère le nœud de cluster s'exécute dans la même machine virtuelle. Si le travail utilisait System.exit, il le fermerait non seulement, mais également "arrêterait le noeud complet". Vous ne pourrez pas envoyer d'autre travail à ce nœud de cluster car le programme de gestion a été fermé accidentellement.
Par conséquent, n'utilisez pas System.exit si vous souhaitez pouvoir contrôler votre programme à partir d'un autre programme Java de la même machine virtuelle.
Utilisez System.exit si vous souhaitez fermer l'intégralité de la machine virtuelle Java à dessein et si vous souhaitez tirer parti des possibilités décrites dans les autres réponses (par exemple, points d'arrêt à la fermeture: point d'arrêt à l'exécution de Java , non -zero renvoie la valeur pour les appels en ligne de commande: Comment obtenir l'état de sortie d'un programme Java dans un fichier de traitement par lots Windows ).
Jetez également un coup d’œil aux exceptions d’exécution: System.exit (num) ou lève une exception RuntimeException depuis main?