【问题标题】:try-catch syntactic sugar in javajava中的try-catch语法糖
【发布时间】:2012-02-07 05:39:24
【问题描述】:

我想知道在 java 中是否有一种方法(纯代码,而不是一些 Eclipse 的东西)来“语法糖”重复 try catch 代码。也就是说,我必须包装一堆函数

public void foo(){
  try{
        // bla
  } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
  }
}

public void bar(){
  try{
        // other bla
  } catch (Exception e) {
            System.out.println("caught exception:");
            e.printStackTrace();
  }
}

等等。我想写

@excepted public void foo(){
// bla
}

@excepted public void bar(){
// other bla
}

我认为这种类型的糖在 python 中是可能的。用Java可以吗?

【问题讨论】:

  • 捕获并将异常转储到标准输出通常是一个糟糕的主意。相反,要么 捕获异常(将其留给调用代码),要么酌情处理它。没有真正的抽象可用于“酌情处理”,因为它取决于“bla”的内容。
  • 如果您不打算做任何特定的事情来处理未捕获的异常,您可以将整个程序包装在一个 try/catch 中
  • 捕获一般的Exception 通常也是一个糟糕的主意,除非您正在编写某种框架代码。

标签: java try-catch syntactic-sugar


【解决方案1】:

你不能像你的伪代码建议的那样做一些带有注释的事情,但你可以让方法抛出:

public void bar() throws Exception {}

让它一直冒泡,随心所欲地捕捉它,在调用树的更高处(或调用堆栈的下方,如果你愿意的话)。

【讨论】:

  • 我会给这个+1 如果它没有抛出Exception,而是更具体的异常类型。我意识到 OP 的问题涉及Exception,但我认为我们不应该鼓励它。想想必须为这个接口编写代码的可怜的家伙。他/她现在也必须抓住并处理一个将军Exception
  • 郑重声明,我完全不同意;我也更喜欢特定类型的Exception,如果它们必须被声明为抛出。我们所有的异常都是RuntimeException,所以不需要声明(但为了API的缘故,它们应该记录在案!!!)
  • 好吧,将私有方法声明为throws Exception,虽然不完全优雅,但对我来说似乎并不坏。
【解决方案2】:

将 try/catch 封装在一个接受接口的类/方法中。将匿名实现传递给该类/方法。只有在涉及异常处理时才真正好用,否则会产生类似的噪音。

您还可以玩 AOP/字节码游戏,具体取决于实际用例。

【讨论】:

    【解决方案3】:

    对于您问题的第一部分,在 Java 7 中有用于捕获重复异常的新语法糖,请查看 article

    对于你问题的第二部分,恐怕Java中没有这样的东西。

    【讨论】:

      【解决方案4】:

      我的建议是使用throws Exception 声明您的方法,或者将它们捕获并重新抛出为RuntimeExceptions

      仅捕获和打印Exceptions 在实践中是一个坏主意,因为尽管您没有采取任何措施从Exception 中恢复,但您仍在继续执行。即使您的代码继续正常运行,很快您将拥有一个包含数百个异常的日志文件,并且对于调试和从中查找有用信息几乎毫无价值。

      try {
         ...
      } catch (Exception e) {
         System.out.println("caught exception:");
         e.printStackTrace();
      }
      

      【讨论】:

        【解决方案5】:

        为了回答这个问题,我假设

        1. 给您一个 Base 类,其中包含一大堆引发异常的非最终方法。
        2. 您应该准备一个扩展 Base 的 Extends 类,但会更改某些方法的行为以记录异常而不是抛出异常。
        3. 您可以访问 Base 的源代码并可以进行修改。

        你可以写一个注解处理器。在 Base 类上放置一个注释,告诉处理器创建 Extension 类。然后在一些方法上,放一个注解告诉处理器记录异常而不是抛出它们。

        这可能比节省下来的工作量更多(编写和调试处理器),具体取决于您的情况。

        您也可以通过编写InvocationHandler 并使用Proxy 来实现所需的结果。

        【讨论】:

          【解决方案6】:

          现在我们有一个自 JDK 7 起名为 try-with-resources 的语法糖,因此,如果您正在使用资源,或者您可以将您的资源包装到实现 AutoCloseable as 的类资源类中

          public class MyResource implements AutoCloseable {
              @Override
              public void close() throws Exception {
                  System.out.println("Closed MyResource");
              }
          }
          

          那么您将摆脱这种负担。

          顺便说一句,如果你像@sarumont 提到的那样尝试,只是让异常冒泡,你可能会丢失原始异常(catch 中的异常会将原始异常隐藏在 try 块中),这是相当不推荐的 因为您使用异常进行故障排除,而错误的异常只会令人困惑。

          【讨论】:

            猜你喜欢
            • 2012-11-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-08-23
            • 1970-01-01
            相关资源
            最近更新 更多