简体   繁体   English

JAVA中的链式异常设施

[英]chained exception facility in JAVA

I can acheive chained Exception facility in java as 我可以在Java中实现链接的Exception设施为

case 1: 情况1:

public static void main(String[] args) {

    try {
        method1();
    } catch (Exception e) {
        System.out.println("Exception in the main method :: "+e);
    }

}

private static void method1() throws Exception {
    try{
        System.out.println("Inside Try Block"+10/0);
    } catch(ArithmeticException e){
        System.out.println("Exception in method1 :: "+e);
        throw e;
    } finally{
        System.out.println("In FinallY Block");
    }

}

case 2 : 情况2:

public static void main(String[] args) {

    try {
        method1();
    } catch (Exception e) {
        System.out.println("Exception in the main method :: "+e);
    }

}

private static void method1() throws Exception {
    try{
        System.out.println("Inside Try Block"+10/0);
    } catch(ArithmeticException e){
        System.out.println("Exception in method1 :: "+e);
        throw (ArithmeticException)new ArithmeticException().initCause(e);
    } finally{
        System.out.println("In FinallY Block");
    }
}

And I got the output as 我得到的输出为

Exception in method1 :: java.lang.ArithmeticException: / by zero
In FinallY Block
Exception in the main method :: java.lang.ArithmeticException: / by zero

And My Question is : 我的问题是:

  1. Is there any difference between these two cases ? 这两种情况有什么区别吗?
  2. Which is the better method ? 哪个更好的方法?
  3. And why 2 cases for the same purpose ? 又为什么有2个案件出于相同目的?
  1. The difference is you wrap the original ArithmeticException exception in another exception of same type in the second case (see below why this is pointless). 区别在于,在第二种情况下,您将原始ArithmeticException异常包装在另一个相同类型的异常中(请参见下面的说明,这是毫无意义的)。

  2. Case 1 is probably what you want to use here, because you don't broaden the meaning of your exception (to a higher level). 案例1可能是您要在这里使用的,因为您没有将异常的含义扩展到更高的层次。

  3. They don't have the same purpose, let me explain... 他们有不同的目的,让我解释一下...

If you set an exception as a cause, it doesn't have the same meaning. 如果将异常设置为原因,则它的含义不同。 You can give a larger meaning to the ArithmeticException by wrapping it in a higher-level exception. 通过将其包装在更高级别的异常中,可以赋予ArithmeticException更大的含义。 Here you're just wrapping it in another ArithmeticException , which does not make sense. 在这里,您只是将其包装在另一个ArithmeticException ,这没有任何意义。

A case where you might want a cause is for instance when you try to get some data from a web service: the low-level methods sending HTTP requests throw some SocketException or HttpException , and you wrap them in some higher-level exceptions describing what resource couldn't be loaded (for instance). 例如,当您尝试从Web服务中获取一些数据时,可能会引起原因:发送HTTP请求的低级方法抛出一些SocketExceptionHttpException ,然后将它们包装在一些高级异常中,这些异常描述了哪些资源无法加载(例如)。

You should pass the cause in as a constructor argument, instead of calling initCause. 您应该将cause作为构造函数参数传递,而不是调用initCause。

In real code you don't see an exception thrown wrapping the same type of exception. 在实际代码中,看不到包装相同类型异常的异常。 The point is to wrap an implementation-level exception in something higher-level, so that the code catching the exception doesn't have a lot of implementation-specific special cases to handle (and implementation details don't bleed through to parts of the code that shouldn't have to care), while the chaining makes sure the original stacktrace is retained. 关键是将实现级别的异常包装在更高级别的内容中,以便捕获该异常的代码没有很多要处理的特定于实现的特殊情况(并且实现细节不会渗漏到代码的某些部分)不需要关心的代码),而链接可确保保留原始的堆栈跟踪。

So you'd do something like: 所以你会做类似的事情:

private static void method1() throws HigherLevelException {
    try{
        System.out.println("Inside Try Block"+10/0);
    } catch(ArithmeticException e){
        throw new HigherLevelException(e);
    }
}

Since a lot of people consider checked exceptions to be a failed experiment (not even dot-net chose to copy them), in a lot of cases the higher level exception tends to be an unchecked exception. 由于许多人认为检查异常是失败的实验(甚至不是点网都选择复制它们),因此在许多情况下,较高级别的异常往往是未经检查的异常。 You'll see this pattern with Spring and Hibernate. 您将在Spring和Hibernate中看到这种模式。

In your first example catching an exception just to rethrow it should not be necessary. 在您的第一个示例中,捕获异常只是为了重新抛出异常就没有必要了。 The stacktrace should be sufficient to determine where the exception was generated without having to log and rethrow. stacktrace应该足以确定在哪里生成异常,而不必记录和重新抛出。 Make sure you have one centralized place that catches and logs exceptions. 确保您拥有一个可捕获和记录异常的集中位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM