【问题标题】:Java Try Catch Finally blocks without CatchJava Try Catch finally 没有 Catch 的块
【发布时间】:2011-06-01 08:57:59
【问题描述】:

我正在审查一些新代码。该程序只有一个 try 和一个 finally 块。由于 catch 块被排除在外,如果 try 块遇到异常或任何可抛出的东西,它是如何工作的?是直接进入finally块吗?

【问题讨论】:

标签: java try-catch finally try-catch-finally try-finally


【解决方案1】:

如果 try 块中的任何代码可以抛出已检查异常,则它必须出现在方法签名的 throws 子句中。如果抛出未经检查的异常,它就会从方法中冒出来。

finally 块总是被执行,无论是否抛出异常。

【讨论】:

  • 第一段不一定正确。 Try 块可以嵌套。任何未捕获的异常,无论是否未经检查,都会从方法中冒出。
  • Try 块可以嵌套,但我不建议这样做。我不会那样写代码。
  • @duffymo:“冒泡出方法”是什么意思?
  • @Anand 只是一些用于“抛出异常”的非技术性语言。
  • 不忽略;传递方法链。
【解决方案2】:

关于try/finally 的一个小说明:finally 将永远执行,除非

  • System.exit() 被调用。
  • JVM 崩溃。
  • try{} 块永远不会结束(例如无限循环)。

【讨论】:

  • try{..} catch{ throw ..} finally{..} 怎么样?我认为 finally 不会被执行
  • 在这种情况下 finally 仍然会被调用。只有原始异常丢失。
  • 之前调用 System.exit() 最后也不会被执行。
  • @jyw 这就是我上面列表中第一项的意思。
  • 我不得不说,这涵盖了所有的基础!
【解决方案3】:

Java 语言规范(1) 描述了try-catch-finally 的执行方式。 没有捕获相当于没有捕获能够捕获给定的 Throwable。

  • 如果 try 块的执行由于抛出值 V 而突然完成,则可以选择:
    • 如果 V 的运行时类型可分配给 try 语句的任何 catch 子句的参数,那么……
    • 如果 V 的运行时类型不可分配给 try 语句的任何 catch 子句的参数,则执行 finally 块。然后有一个选择:
      • 如果 finally 块正常完成,则 try 语句会因为抛出值 V 而突然完成。
      • 如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成(并且值 V 的抛出被丢弃并被遗忘)。

(1)Execution of try-catch-finally

【讨论】:

    【解决方案4】:

    内部 finally 在将异常抛出到外部块之前执行。

    public class TryCatchFinally {
    
      public static void main(String[] args) throws Exception {
    
        try{
            System.out.println('A');
            try{
                System.out.println('B');
                throw new Exception("threw exception in B");
            }
            finally
            {
                System.out.println('X');
            }
            //any code here in the first try block 
            //is unreachable if an exception occurs in the second try block
        }
        catch(Exception e)
        {
            System.out.println('Y');
        }
        finally
        {
            System.out.println('Z');
        }
      }
    }
    

    结果

    A
    B
    X
    Y
    Z
    

    【讨论】:

    • 添加一个“return;”在第一个“finally”块中,结果将打印 A、B、X、Z 而没有 Y。有人知道为什么吗?本质上,这个添加的“返回”会掩盖抛出的异常?
    【解决方案5】:

    finally块总是在try块结束后运行,无论try正常结束还是异常异常结束,呃,throwable。

    如果 try 块中的任何代码抛出异常,则当前方法只需重新抛出(或继续抛出)相同的异常(在运行 finally 块之后)。

    如果 finally 块抛出异常/错误/throwable,并且已经有一个待处理的 throwable,它会变得丑陋。坦率地说,我完全忘记了发生了什么(对于我多年前的认证而言)。我认为两个 throwable 都链接在一起,但是您必须做一些特殊的巫术(即 - 我必须查找的方法调用)才能在“最终”被吐出之前解决原始问题,呃,吐了。

    顺便说一句,try/finally 对于资源管理来说是很常见的事情,因为 java 没有析构函数。

    例如-

    r = new LeakyThing();
    try { useResource( r); }
    finally { r.release(); }  // close, destroy, etc
    

    “最后”,还有一个提示:如果您确实费心放入一个 catch,要么捕获特定(预期的)可投掷子类,要么只捕获“Throwable”, em> “异常”,用于一般的包罗万象的错误陷阱。太多的问题,例如反射错误,抛出“错误”,而不是“异常”,并且这些问题将被任何“catch all”编码为:

    catch ( Exception e) ...  // doesn't really catch *all*, eh?
    

    改为这样做:

    catch ( Throwable t) ...
    

    【讨论】:

    • 查看下面 Carlos Heuberger 的回答,了解丑陋的部分。
    【解决方案6】:

    版本 7 之前的 Java 版本允许 try-catch-finally...

    的这三种组合
    try - catch
    try - catch - finally
    try - finally
    

    无论try 或/和catch 块中发生什么,finally 块将始终被执行。所以如果没有catch块,这里就不会处理异常。

    但是,您仍然需要在代码中的某处使用异常处理程序——当然,除非您希望您的应用程序完全崩溃。这取决于您的应用程序的架构,该处理程序的确切位置。

    • Java try 块后面必须跟 catch 或 finally 块。
    • 对于每个 try 块,可以有零个或多个 catch 块,但只有一个 finally 块。
    • 如果程序退出(通过调用 System.exit() 或通过导致导致进程中止的致命错误),将不会执行 finally 块。

    【讨论】:

    • "before version 7 allow" 您是否暗示 Java 7 和 Java 8 不允许这三种组合?我怀疑这就是你的意思,但这就是你的回答所暗示的。
    • 如果try块中有return语句,是否执行finally块?
    • @Rahul 是的,最后会被调用。参考:stackoverflow.com/questions/65035/…
    • @Aaron - try-with-resource 的新语法,它在 try 关键字之后的括号内构造的任何内容上自动调用 .close()。
    • @Roboprog 你是对的,但是资源必须实现 Autocloseable 接口
    【解决方案7】:

    try 块是如何工作的 遇到异常或任何事情 可扔的

    异常被抛出块外,就像在任何其他没有被捕获的情况下一样。

    无论 try 块如何退出,finally 块都会执行——无论是否有任何 catch,无论是否有匹配的 catch。

    catch 块和 finally 块是 try 块的正交部分。你可以有一个或两个。使用 Java 7,您将无法拥有这两者!

    【讨论】:

      【解决方案8】:

      你不试试那个程序吗?它将转到 finally 块并执行 finally 块,但是不会处理异常。但是,这个异常可以在 finally 块中被否决!

      【讨论】:

        【解决方案9】:

        finally 块在 try 块完成后执行。如果 try 块离开时抛出了一些东西,则执行 finally 块。

        【讨论】:

          【解决方案10】:

          try 块中,我们编写可以引发异常的代码。 catch 块是我们处理异常的地方。 无论是否发生异常,finally 块都会一直执行。

          现在如果我们有 try-finally 块而不是 try-catch-finally 块,那么异常将不会被处理,并且在 try 块而不是控制去 catch 块之后它将进入 finally 块。 当我们不想对异常做任何事情时,我们可以使用 try-finally 块。

          【讨论】:

            【解决方案11】:

            无论try 块中是否抛出异常 - finally 块都将被执行。异常不会被捕获。

            【讨论】:

              猜你喜欢
              • 2015-09-05
              • 2012-03-06
              • 1970-01-01
              • 1970-01-01
              • 2011-10-31
              • 2014-11-27
              • 1970-01-01
              • 2011-11-17
              • 1970-01-01
              相关资源
              最近更新 更多