【问题标题】:How to make code run only if an exception was thrown?仅在引发异常时如何使代码运行?
【发布时间】:2011-09-27 01:49:58
【问题描述】:

之后我尝试了几个不同的捕获。我有一些“清理”代码,只有在抛出异常时才应该运行。我可以为每个异常添加相同的代码,但这成为维护的噩梦。基本上,我想要类似 finally 语句的东西,但它只在抛出异常时运行。

这可能吗?

【问题讨论】:

  • 这些运行时错误是您捕获的还是您自己的业务错误。
  • IOException、ClientProtocolException、UnsupportedEncodingException 等

标签: java exception


【解决方案1】:

不幸的是,没有直接的支持。像这样的东西怎么样

boolean successful = false;
try {
    // do stuff
    successful = true;
} catch (...) {
    ...
} finally {
    if (!successful) {
        // cleanup
    }
}

【讨论】:

    【解决方案2】:

    我唯一能想到的就是在每个 catch 中设置一个变量,然后在 finally 中检查该变量。

    伪代码:

    Boolean caught = false;
    
    try {
    
        //risky code here
    
    catch(err) {
        caught = true;
        // Do other stuff
    }
    catch(err) {
        caught = true;
        // Do other stuff
    }
    catch(err) {
        caught = true;
        // Do other stuff
    }
    finally {
       if (caught) {
           // Do clean up
       }
    
    }
    

    【讨论】:

      【解决方案3】:

      我可以为每个异常添加相同的代码,但这会成为维护的噩梦。

      或者如果你抹去“例外”:

      我可以向每个 [地点] 添加相同的代码,但这将成为维护的噩梦。

      这就是方法的用途。

      private void cleanup() { /* clean up */ }
      
      ...
      
      try {
          // oh noes
      
      } catch (MyException me) {
          cleanup();
      } catch (AnotherException ae) {
          cleanup();
      }
      

      无需维护!

      【讨论】:

      • 除了现在您无法访问调用者内部的内容。如果那是需要清理的地方,那你就完蛋了。如果你把乱七八糟的东西传进去,那么你就是在硬编码要修复的东西列表——如果这个列表以后发生变化,你必须改变每个使用它的地方。你会错过一个。
      • 哦,这个cleanup函数应该肯定private,如果你坚持要它的话。
      • @cHao 虽然 ture 和 finally 肯定更好,但如果你错过了一个地方,代码就无法编译,所以还是没那么糟糕
      【解决方案4】:

      为什么不直接使用简单的 try & catch?

      try
      {
          foo();
      }
      catch(Exception1 e1)
      {
          dealWithError(1);
      }
      catch(Exception2 e2)
      {
          dealWithError(2);
      }
      catch(Exception3 e3)
      {
          dealWithError(3);
      }
      
      ...
      
      private void dealWithError(int i)
      {
          if(i == 1) // deal with Exception1
          else if(i == 2) // deal with Exception2
          else if(i == 3) // deal with Exception3
      }
      

      【讨论】:

      • 这正是没有人应该做的事情。 if 街道上的噩梦。
      【解决方案5】:

      您可以尝试包装两层异常处理程序,并在完成通用处理后重新抛出异常:

          try {
              try {
                  // your code goes here
      
              } catch (Throwable t) {
                  // do common exception handling for any exception
                  throw t;
              }       
      
          } catch (NullPointerException nx) {
              // handle NPE
          } catch (Throwable t) {
              // handle any other exception
          }
      

      虽然我不确定我是否真的喜欢这个解决方案......感觉有点像黑客。我可能宁愿看到在每个实例中显式处理异常,即使这意味着重复调用某种共享清理函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-13
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 1970-01-01
        • 2013-07-17
        相关资源
        最近更新 更多