Java中是否存在"noreturn"关键字

Xia*_* Li 4 java compiler-construction return

有时我想写一个error()函数,它最终肯定会调用System.exit(),这意味着这个函数永远不会返回.但是,如果我在其他函数中调用error(),我想写如:

int fun() {
...
  error();
}
Run Code Online (Sandbox Code Playgroud)

但是编译器坚持在error()调用之后返回一个int值,因为它不知道error()永远不会返回.我肯定会返回一个任意的int,但如果返回类型是一个复杂的类,我需要在代码中构造它,这是浪费时间.有没有办法告诉编译器函数永远不会返回?

Ste*_*n C 6

在Java方法签名中,您无法告诉编译器该方法无法返回.没有它,编译器别无选择,只能假设它可能会返回.(实际上,关于可达性/明确赋值的JLS规则将明确说明这一点......如果你愿意通过它们.)

我在两种方法之间摇摆不定:

int fun() {
    ...
    error();
    return 0;  // NOT REACHED
}
Run Code Online (Sandbox Code Playgroud)

int fun() {
    ...
    error();
    throw new AssertionError("not reached");
}
Run Code Online (Sandbox Code Playgroud)

两者都不完全令人满意.

在第一个版本中,注释很重要,因为有人第一次阅读您的代码可能没有意识到error永远不会返回.

第二个版本更强大,因为如果有人改变error方法的行为以使其实际返回,它将给你"快速失败" .(第一个版本将导致该fun方法返回虚假值......可能导致其他意外后果.)


在一个相关的点上,通过调用拉动JVM上的插件的方法System.exit()可能会有问题.更好的想法是抛出一个未经检查的"结束世界"异常并将其捕获到主线程的最外层.对于在其他线程上抛出的异常,一个想法是安装默认的未捕获异常处理程序,该处理程序Thread.interrupt()用于通知主线程已抛出"结束世界"异常.

但重点是System.exit()在代码中深入调用是有问题的; 例如,如果您重新调整代码以在更大的框架内运行; 例如在网络容器中.


Ami*_*ani 5

你应该抛出一个RuntimeException.