如何让Java编译器识别不可达代码,无需冗余return null即可编译?
解决Java中System.exit后仍需冗余return的问题
Java编译器的控制流分析不会把System.exit()当作方法的终止标记——它只认可return、throw或者方法正常结束作为路径终点。所以哪怕你在catch块里调用了System.exit(1),编译器依然认为后续还有代码需要执行,因此强制要求添加return语句。
下面是几种消除冗余return的可行方案:
方案一:自定义未检查异常抛出
创建一个继承自RuntimeException的自定义异常,在调用System.exit后抛出它。编译器会识别到throw语句是方法的终止点,不再要求后续的return。
// 自定义异常,可放在项目通用异常模块中 private static class ExitException extends RuntimeException {} private Inet4Address setServerAddress() { try { if (somethingTrue()) { return (Inet4Address) Inet4Address.getByName("127.0.0.1"); } return (Inet4Address) Inet4Address.getByName(getIP4()); } catch (UnknownHostException e) { System.out.println("Error at getting the server address from command line. (" + e.getMessage() + ")"); System.exit(1); throw new ExitException(); // 编译器判定方法在此终止 } // 无需再写return null }
方案二:封装System.exit到带抛出的工具方法
把System.exit封装到一个工具方法里,方法末尾抛出一个断言错误。调用这个方法后,编译器会判定后续代码完全不可达,自然不需要return。
private static void terminate(int exitCode) { System.exit(exitCode); throw new AssertionError("Unreachable code after System.exit"); } private Inet4Address setServerAddress() { try { if (somethingTrue()) { return (Inet4Address) Inet4Address.getByName("127.0.0.1"); } return (Inet4Address) Inet4Address.getByName(getIP4()); } catch (UnknownHostException e) { System.out.println("Error at getting the server address from command line. (" + e.getMessage() + ")"); terminate(1); } // 无需return语句 }
方案三:直接抛出普通RuntimeException(快速但可读性差)
如果不想自定义异常,也可以直接在System.exit后抛出普通的RuntimeException,虽然简单但语义不够清晰,不推荐在大型项目中使用。
private Inet4Address setServerAddress() { try { if (somethingTrue()) { return (Inet4Address) Inet4Address.getByName("127.0.0.1"); } return (Inet4Address) Inet4Address.getByName(getIP4()); } catch (UnknownHostException e) { System.out.println("Error at getting the server address from command line. (" + e.getMessage() + ")"); System.exit(1); throw new RuntimeException(); } }
本质上,这些方案都是利用throw语句让编译器明确感知到方法在此处终止,从而消除对冗余return的要求。
内容的提问来源于stack exchange,提问作者João Barroso
相关产品推荐
相关产品推荐

