【问题标题】:Unreachable return statement still throws error无法访问的返回语句仍然抛出错误
【发布时间】:2014-01-24 15:25:07
【问题描述】:

我有这个非常简单的代码sn-p:

static String getInput() throws IOException{
  if(in.ready()){
      return in.readLine().trim();
  }
  System.err.println("Please provide more input in order to execute the program.");
  System.exit(0);
  return "";
}

据我所知,JVM 不可能在代码末尾执行 return 语句。但是如果我注释掉这一行,java 会抱怨缺少 return 语句。为什么 JVM 不能识别 System.exit(0) 不允许执行任何其他代码,但如果 return 不允许执行代码,则会抱怨无法访问的语句? 我认为最后的 return 语句是多余的,可能会让其他开发人员感到困惑,那么为什么 java 不让我摆脱它呢?

【问题讨论】:

  • System.exit(0);就编译器而言只是一种方法,SecurityManager 可以阻止它做任何事情。例如,如果您在应用程序服务器中调用它,您不希望它杀死所有应用程序。

标签: java jvm unreachable-code


【解决方案1】:

为什么 JVM 不能识别 System.exit(0) 将不允许执行任何其他代码,但如果 return 不允许执行代码,则会抱怨无法访问的语句?

这不是 JVM - 它是 编译器。而且编译器不知道 library 调用会做什么——它只知道 language 规则。 (特别是JLS section 14.21, Unreachable Statements。)

例如:

public int foo() {
    alwaysThrow();
    // This is required.
    return 10;
}

private static void alwaysThrow() {
    throw new RuntimeException();
}

public int foo() {
    throw new RuntimeException();
    // Error: unreachable statement
    return 10;
}

就编译器而言,简单的内联改变了代码的含义。

这可以通过返回类型“从不”来“修复”——表示“此方法永远不会正常返回——它要么挂起要么抛出异常”,但这根本不是语言的一部分(并且会有自己的并发症)。如果您有兴趣,Eric Lippert 有几篇关于 C# 主题的博文(位置类似):part onepart two

【讨论】:

  • 同意。编译器只是检查所有可能的执行路径上是否有返回值。它不“知道” System.Exit(0) 意味着 return "" 不会被执行。为什么你会这样的事情(system.exit)是读者需要考虑的话题。
  • @jonSkeet 感谢您准确快速的回答,将尽快接受!
  • @robnick 是 System.exit 不好的约定?这个特殊的项目是针对对堆栈跟踪不太感兴趣的人群,这就是为什么我选择更简短的错误消息。
  • @janDro:我会在顶层捕获异常并退出那里而不是这里。使用任意方法调用System.exit 感觉是个坏主意。
猜你喜欢
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 2016-09-27
  • 2010-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-02
相关资源
最近更新 更多