int fun() {
...
error();
}
但编译器坚持在错误(error())调用后返回一个int值,因为它不知道error()永远不会返回。 我肯定可以返回任意int,但如果返回类型是一个复杂的类,则需要在代码中构建它,这是一种浪费时间的方式。有没有办法告诉编译器函数永远不会返回?
int fun() {
...
error();
}
但编译器坚持在错误(error())调用后返回一个int值,因为它不知道error()永远不会返回。 我肯定可以返回任意int,但如果返回类型是一个复杂的类,则需要在代码中构建它,这是一种浪费时间的方式。有没有办法告诉编译器函数永远不会返回?
在Java方法签名中,没有办法告诉编译器该方法不会返回值。缺少这一信息,编译器只能假设该方法可能会有返回值。(事实上,JLS关于可达性/明确赋值的规则也明确说明了这一点……如果你想深入了解的话。)
我在两种方法之间徘徊:
int fun() {
...
error();
return 0; // NOT REACHED
}
int fun() {
...
error();
throw new AssertionError("not reached");
}
两者都不是完全令人满意的。
在第一个版本中,注释很重要,因为第一次阅读代码的人可能没有意识到error
永远不会返回。
第二个版本更加健壮,因为如果有人改变了error
方法的行为,使其实际返回,它将给你一个“快速失败”。(第一个版本将导致fun
方法返回虚假值...可能导致其他意外后果。)
在相关的一点上,通过调用System.exit()
来关闭JVM的方法可能会有问题。更好的方法是抛出一个未检查的“结束世界”异常,并在主线程的最外层捕获它。对于在其他线程上抛出的异常,一个想法是安装一个默认的未捕获的异常处理程序,该处理程序使用Thread.interrupt()
通知主线程已经抛出了“结束世界”的异常。
但是问题在于,在代码深处进行System.exit()
调用可能会有问题;例如,如果您重新设计您的代码以在更大的框架内运行;例如,在Web容器中。
你应该抛出一个RuntimeException。
RuntimeException
异常而不是调用System.exit()
(应该是这样的情况),那么实际上肯定会有可能抛出异常。 - Kirk Wollprivate RuntimeException error() {
throw new EndOfTheWorldException();
// Java knows that code after throw will not be reached
// so no return is required here. Or, if you insist, you
// could call System.exit() and return null afterwards.
}
int fun() {
// ...
throw error();
// Again, no need for a return here, the compiler understands
// that the statement above won't return.
}
或者更明确地说,您可以重构此代码,使error()
成为要抛出的异常的工厂:
private RuntimeException makeError() {
return new EndOfTheWorldException();
}
int fun() {
throw makeError();
}
不确定为什么你想这样做。如果你抛出一个异常,代码会更加清晰、易于测试和维护;你可以使用 Thread.setDefaultUncaughtExceptionHandler()
来退出。
但是如果你坚持:
public class HaltAndCatchFireError extends Error {
public HaltAndCatchFireError() {
System.exit(1);
}
}
然后在你想要退出的地方:
int fun() {
...
throw new HaltAndCatchFireError();
}
返回0,或在复杂情况下返回null。
你的函数是否有返回值?如果没有,你想让你的函数成为 void 类型:
void fun() {
...
}
你可以写
error();
return;
但是您可能需要重新考虑您的方法。这可能不是非常面向对象的方法。
RuntimeException
。 - bluefoot
System.exit()
呢? - S.Lott