【问题标题】:Unreachable statement explanation required需要无法到达的语句解释
【发布时间】:2014-08-02 20:46:04
【问题描述】:

我正在准备 OCA Java 考试,但答错了这个问题。我不明白为什么return 语句无法访问。我的想法是即使抛出异常也会被捕获,执行finally块中的语句然后执行return语句,还是如果抛出异常线程不执行return语句?更一般地说,有人可以解释在引发异常的情况下会发生什么以及在哪些情况下执行 finally 块之后的语句的规则。对于某些问题,我是正确的,而对于其他问题,我不是,所以我不清楚这里的确切编译器规则。

public float parseFloat(String s){
   float f = 0.0f;
   try{
      f = Float.valueOf(s).floatValue();
      return f ;
   }
   catch(NumberFormatException nfe){
      System.out.println("Invalid input " + s);
      f = Float.NaN ;
      return f;
   }
   finally { System.out.println("finally");  }
   return f ;
}

【问题讨论】:

  • 因为try/catch 块中的return f; 语句之一运行。
  • @August 这里的Java编译器分析引擎没有考虑到——在try中也可能抛出不同异常(确保没有返回值) ,这样就不会运行任何返回。即把Float.valueOf(s).floatValue()替换成float f(),其中的内容并不重要——分析不会改变。
  • java-samples.com/showtutorial.php?tutorialid=296 。如果没有异常,最终发生(就在第一个 return f; 之前)一旦完成它就会返回(然后不要调用 last return f)。如果有 NumberFormatException,同样适用,最后一种可能性是一个不是 NumberFormatException 的异常,在这种情况下,异常没有被捕获,然后它被传递给父级,但最终会发生,在 finally 结束时将传递异常。然后永远不会达到最后一个 return f 。 finally 总是被调用,并让最后一个动作在 finally 结束时等待以完成它。

标签: java


【解决方案1】:
  1. 如果发生异常,代码立即退出
  2. 然后检查是否有匹配的 catch 语句,如果有,则运行代码
  3. 无论 trycatch 块内部发生什么,finally 部分都将始终运行。
  4. 如果 catch 块本身没有返回或抛出异常,try/catch/finally 之后的代码将继续运行。
  5. 这在您的代码中是不可能的,因为在成功的情况下您的 try 块会返回,而在失败的情况下您的 catch 块会返回。

因此可能存在一种理论上的情况,您的代码会有意义:如果 try{} 块内的代码会抛出除 NumberFormatException 之外的任何其他异常。这只有在未经检查的异常(您不需要捕获的异常)的情况下才有可能。编译器无法知道或检查这一点,因此除非您为其编写第二个 catch 块,否则不允许此类代码。 (如果你现在感到困惑:忘记我说的话,这对你的任务并不重要)

以下是此类案例的示例:

public float parseFloat(String s){
   float f = 0.0f;
   try{
      SomeOtherClass.doStuffWhichFailsWithRuntimeException();
      return f;
   }
   catch(NumberFormatException nfe){
       // will not run, because the thrown exception is not of type NumberFormatException
   }catch(Exception e){
       // any other failure besides NumberFormatException
       // considered bad practice: If you do not know what fails, do not try to recover from it, it's most likely very bad.
      return f;
   }
   finally { 
      // this will run after the catch block was run
      System.out.println("finally");  
   }

   // theoretically reachable, but compiler does not allow it because he cannot check it.
   //return f ;
}

【讨论】:

  • 最后一点非常要记住 Java 分析的工作原理,很好地指出来。
【解决方案2】:

如果发生异常,则运行 catch 块,返回 f,最后运行块。 最后一个

返回 f;

永远不会到达。

【讨论】:

  • 如果抛出不同(非 NumberFormatException)异常怎么办? Java 分析考虑抛出了哪个异常(如果有)(或者可能从 try 中的代码中抛出)。
  • @user2864740 然后应用程序可能像所有未捕获的异常一样被终止
  • @Gumbo 可能,但是在这种分析中考虑这一点很重要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
相关资源
最近更新 更多