我的 java 应用程序中有一组错误代码。目前我正在使用System.exit(code);
将错误代码从应用程序返回到外部应用程序。是否有任何替代方法System.exit
使用这是不好的做法,因为它可能会关闭整个 JVM。
3 回答
我过去分享过你的经验,并试图设计出来System.exit()
。一种可能性是留下RuntimeException
未捕获的内容,然后您将返回1
shell,但最终,如果您想要比这更多的多功能性(并且不希望丑陋的堆栈跟踪污染您的输出),您必须至少有“一个”调用到System.exit()
.
public class Splat {
public static void main(String[] args) {
if (args.length > 0 && "splat".equals(args[0]))
throw new RuntimeException("splat");
}
}
输出:
$ java Splat
$ echo $?
> 0
$ java Splat splat
> Exception in thread "main" java.lang.RuntimeException: splat
> at Splat.main(Splat.java:9)
$ echo $?
> 1
我这样做的原因是我们的组织开始使用声纳的静态分析结果作为 KPI,而我的工作是降低数字。这是做任何事情的可怕理由,但仍然是一个有趣的工程挑战......
我尝试的一种方法是抛出一个特定的类RuntimeException
,带有一个退出代码实例变量,并在外部范围内捕获它。这样,您就可以确定当您确实谋杀虚拟机时,无论如何您都处于堆栈的尾部......
public class Splat {
public static final class Exit extends RuntimeException {
private int exitCode;
public Exit(int exitCode) {
this.exitCode = exitCode;
}
}
public static void main(String[] args) {
try {
wrappedMain(args);
} catch (Exit e) {
System.exit(e.exitCode);
}
}
public static void wrappedMain(String[] args) {
if (args.length > 0 && "splat".equals(args[0])) {
int code = (args.length > 1) ? Integer.parseInt(args[1]) : 0;
throw new Exit(code);
}
}
}
输出:
$ java Splat
$ java Splat splat
$ echo $?
> 0
$ java Splat splat 1
$ echo $?
> 1
> $ java Splat splat 2
$ echo $?
> 2
$ java Splat splat -1
$ echo $?
> 127
当然,这种方法有一些警告!这是一种奇怪的退出方式,任何不熟悉您的约束的人都会摸不着头脑。另外,如果catch (Throwable t)
以后有人这样做,那么您将无法退出!如果您在静态分析 CI 环境中工作,那么应该很快将其突出显示为更严重的违规行为!
正如已经评论过的:当您在批处理或 shell 中等待某些代码时,您实际上是在等待程序完成,这意味着您的 java 程序退出,JVM 也是如此。唯一的方法就是System.exit(code)
像你已经在做的那样使用。
如果您正在谈论一个进程的退出代码,那么System.exit(int)
就是要走的路,因为您希望整个进程退出,因此 JVM 也应该关闭。
但是,如果您想向批处理或 shell 发送一些错误消息(不退出进程),那么您将不得不使用System.err.println()
. 这将写入错误流而不是输出流。