不能阻止 System.exit() 执行,但可通过 SecurityManager 拦截、替代退出机制(如 SpringApplication.exit)、避免误用等方式防范;Java 17+ 默认禁用 SecurityManager,推荐根本不用 System.exit()。

System.exit() 本身不是用来阻止 JVM 退出的,而是主动触发 JVM 立即退出的指令。所以问题“怎么阻止 JVM 正常退出”如果理解为“如何防止 System.exit() 生效”,那答案是:不能阻止它执行(一旦调用就必然退出),但可以提前拦截、禁止或绕过它的调用。
真正可行的方向是:
- 防止意外或非法调用
System.exit() - 在它生效前做清理
- 用替代机制避免依赖它
以下是具体做法:
✅ 启用 SecurityManager 拦截 exit 调用
JVM 提供了权限控制机制:
立即学习“Java免费学习笔记(深入)”;
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int status) {
throw new SecurityException("System.exit() is forbidden");
}
});之后任何 System.exit(...) 都会抛出 SecurityException,主线程终止(若未捕获),JVM 不会退出——除非还有其他非守护线程在运行。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
⚠️ 注意:
- Java 17+ 默认禁用 SecurityManager,需显式启用(
--security-manager)且多数现代框架(如 Spring Boot)不兼容; - 容器环境(如 Tomcat、K8s)通常已内置限制,无需手动配置。
✅ 用 Runtime.halt() 不是阻止,而是更暴力退出
Runtime.getRuntime().halt(status) 会跳过 shutdown hook 和所有清理逻辑,比 System.exit() 更彻底。但它仍是“退出”,不是“阻止退出”。
✅ 在关键位置加防护:检查并拒绝非法 exit
可在主流程入口或测试启动时主动检测:
if (System.getSecurityManager() == null) {
// 可选:记录警告,或抛异常提醒开发误用
System.err.println("Warning: System.exit() may be called unchecked");
}这不能阻止,但能暴露风险。
✅ 替代思路:根本不用 System.exit()
这才是最可靠、最现代的做法:
- 命令行工具:用
return或抛异常,由main方法自然结束; - Spring Boot 应用:用
SpringApplication.exit(context, code),它会触发完整生命周期销毁; - 多线程程序:用
shutdown()+awaitTermination()关闭线程池,再让主线程退出; - Web 服务:依赖容器管理(Tomcat 自动 stop,K8s 发送 SIGTERM)。
❌ 不能做的事
- 在
finally块里写return或throw来“覆盖”System.exit()—— 无效,exit后代码根本不执行; - 试图用
Thread.sleep()或锁等待来“拖住” JVM —— 无意义,exit是进程级指令,不走 Java 控制流; - 在 shutdown hook 里调用
System.exit()—— 会导致死锁或未定义行为。
不复杂但容易忽略

















