为什么即使在System.exit(0)之后也需要返回;

Nit*_*jer 29 java return

考虑这个功能:

public boolean foo(){
   System.exit(1);
   //The lines beyond this will not be read
   int bar = 1;                  //L1
   //But the return statement is required for syntactically correct code
   return false;                 //L2

   //error here for unreachable code
   //int unreachable = 3;        //L3

}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么L1和L2明显无法访问不会发出警告但L3会发出警告.

biz*_*lop 44

因为就编译器而言,System.exit()只是另一种方法调用.

它所做的是结束这个过程的事实只能从实现中找到(这是本机代码,而不是它有任何区别).

如果你必须把System.exit()你的代码(通常也最好避免它,除非你想返回0以外的代码),它应该是一个返回的方法void,main()例如.这样更好.

至于可达性,解释是相同的:return是Java语言的关键字,因此IDE使用的编译器或解析器可以return说明在执行语句之后理论上代码是不可能的.这些规则的定义在这里.

  • 是的,通常不需要调用`System.exti()`.只需从`main`方法返回即可退出程序. (4认同)
  • 事实上,你甚至可以调用另一个方法`foo()`,它反过来调用`System.exit(..)`所以我们知道`foo()`永远不会返回,但编译器无法检查所有可能的情况. (3认同)
  • **不,应该始终使用System.exit()!**如果你只是让程序自然死掉,你会偶尔得到这个错误输出(在Windows上花了不到10次尝试,Java 1.8. 0_74):"错误:JDWP无法获取JNI 1.2环境,jvm-> GetEnv()返回代码= -2 [等]"这是[已知](/sf/ask/155801621/ jdwp-unable-to-get-jni-1-2-environment)Java bug.此外,一些Swing组件(我认为例如文件对话框.)一旦使用,就会阻止程序*自然地死亡.请参阅[此处](/sf/answers/218038901/). (3认同)

Jon*_*eet 13

Java编译器对此一无所知System.exit.就它而言,它只是一种方法 - 所以语句的结尾是可达的.

这么L1并且L2"明显无法到达"但这只是因为你知道是什么System.exit.语言没有 - 虽然它确实知道return语句的作用,但它知道L3实际上是不可达的.

我有时会想这将是能够声明的方法不仅是有用的void,但从来没有正常结束-它永远只是返回(虽然它可能会抛出异常).然后,编译器将能够使用该信息来使任何调用表达式的结束无法访问,从而防止出现此类问题.然而,这只是我周围的语言设计的梦想- Java的具有类似的话,这将是一个非常糟糕的主意让编译器"知道"特定的JRE方法永远不会正常返回,当这个概念不能被表达直接在语言中.

相反,编译器受JLS第14.21节的规则约束,包括:

  • 如果块可以访问,则非空块中不是交换块的第一个语句是可到达的.
  • 如果S之前的语句可以正常完成,则非空交换块中的每个其他语句S都是可到达的.

...

如果表达式可以访问,则表达式语句可以正常完成.

(方法调用是表达式语句.)

然后从8.4.7节:

如果声明方法具有返回类型,则如果方法的主体可以正常完成,则会发生编译时错误(第14.1节).

并在14.1:

除非另有说明,否则如果所有表达式都在计算并且它执行的所有子语句正常完成,则语句正常完成.

因此,System.exit()就编译器而言,调用可以正常完成,这意味着方法的主体foo可以正常完成,从而导致错误.


And*_*lov 7

从语言的角度来看,只有两种方法可以逃避当前的范围:returnthrow.方法调用永远不会被认为是相同的方式,即使它们只包含代码行:

void method() {
  throw new RuntimeException();
}
Run Code Online (Sandbox Code Playgroud)

更.理论上,任何方法调用都可能导致RuntimeException抛出.在这种情况下,编译器应该给你绝对任何不在try块内的方法调用的警告:

...
method(); // WARNING: may throw in theory
anotherMethod(); // WARNING: possible unreachable code, also may throw
anotherMethod2(); // WARNING: possible unreachable code, also may throw
// etc
...
Run Code Online (Sandbox Code Playgroud)

对于你的问题,逻辑是一样的.


adr*_*on3 7

我:"在退货声明之后可以执行任何事情吗?"
Java:"不."

我:"我可以在调用System.exit后执行任何操作吗?"
Java:"这是一种方法,我不知道它做了什么 - 它不是一个保留的关键字,据我所知,它不会影响程序流程"(它甚至可能不起作用(我不知道退出可以抛出异常(或它的未来变体)))