为什么“catch”块必然要求异常类型?

时间:2015-06-02 13:48:03

标签: java exception error-handling exception-handling runtime-error

就java中的异常处理而言,我已经看到所有try-catch块都需要一种它必须处理的异常,更常见的是:

 catch(Exception e){
 System.out.println("Error occured");
}

现在我的问题是为什么它需要Exception e,因为它没有在任何地方使用?

我的 第二个问题 ,关于我刚才写的以下代码:

Scanner scanner = new Scanner(System.in);
    int x = 1;

    do {
        try {

            System.out.println(" Enter your first number:");
            int n1 = scanner.nextInt();
            System.out.println(" Enter your second number:");
            int n2 = scanner.nextInt();
            int result = n1 / n2;
            System.out.println("");
            System.out.println("The result is : " + result);
            x = 2;

        } catch (ArithmeticException arithmeticException) {
            System.out.println("Error occured");

        }

    } while (x == 1);

}

在上面的一段代码中,我看到程序使用的参数都是catch (ArithmeticException arithmeticException)catch(Exception e)那么这两种不同类型的错误如何与同一代码块一起使用?

7 个答案:

答案 0 :(得分:3)

您的catch块中未使用Exception e参数,但它可用于显示有关捕获的异常的信息(异常' s消息,堆栈跟踪等...) 。您可以决定在catch块中抛出一种新类型的异常,在这种情况下,您可以将e传递给新异常的构造函数。

例如:

catch(Exception e){
    e.printStackTrace ();
}

异常是类的实例,具有类型X异常的catch块可以捕获任何类型为X的异常或X的子类。因此,catch(Exception e)catch (ArithmeticException arithmeticException)都可以赶上ArithmeticException。 (因为ArithmeticExceptionException)的间接子类。

正如Andy评论的那样,您通常应该更喜欢捕获最具体的异常类型(在您的示例中为ArithmeticException),以确保您只捕获您想要捕获的异常。例如,在您的代码catch (Exception e)中也会捕获其他异常 - NoSuchElementExceptionIllegalStateException可能会被scanner.nextInt()抛出。

答案 1 :(得分:0)

这是因为ArithmeticExceptionException的孩子。这是面向对象编程(OOP)的基本原则:https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

它基本上意味着ArithmeticException也是Exception(嗯,它继承自它)。但Exception不一定是ArithmeticException,也可以是IllegalArgumentExceptionException的任何其他孩子。

答案 2 :(得分:0)

您总是catchException - 这是异常处理的本质,因此java语言需要catch块来捕获Exception。通常,您可能希望做一些比在标准输出上打印“Error occurred”更有用的东西,比如抛出自己的异常或获取堆栈跟踪,在这种情况下,您将使用e对象。

关于你的第二个问题,Exception只是一个类,有很多子类,其中一个是ArithmeticException。因此,当您在catch块中看到ExceptionArithmeticException都工作时,它只是继承工作。

答案 3 :(得分:0)

回答第二个问题。 ArithmeticException在尝试解析不是scanner.nextInt()之类的数字时会抛出one

由于ArithmeticException继承自Exception,因此两个catch签名都有效以捕获可能的ArithmenticExction。使用Exception的抓取签名还会捕获其他错误,例如IOExceptionNullPointerException

答案 4 :(得分:0)

  

为什么它需要Exception e,因为它没有在任何地方使用?

因为应该使用。该代码实际上忽略了有关错误的信息并打印出通用且无用的消息。该例外包含有关发生的事情的信息,对于纠正问题至关重要。它应该至少记录在某个地方。

  

这两种不同类型的错误如何与同一代码块一起使用?

代码块中的各种操作可能以各种方式失败。有时可能有必要以不同于另一种类型的方式处理故障。例如,如果数据库交互失败,您可能需要记录错误并通知DBA并完全终止应用程序,但如果发生算术错误,那么您可能希望通知开发人员并返回默认值并允许应用程序继续

了解捕获异常与处理异常有很大不同。如何处理异常(即系统如何逻辑响应错误条件)完全取决于应用程序的逻辑。有些错误是可以恢复的,有些则不是。有些意味着更重要的问题,有些则没有。通过使用多个catch块以不同方式响应不同类型的错误,您可以有意义地处理这些不同的错误条件。

答案 5 :(得分:0)

你有两个问题,让我们按正确的顺序回答。

  

现在我的问题是为什么它需要Exception e,因为它没有在任何地方使用?

基于错误的编码示例提出了这个问题,这个例子甚至没有记录异常类型,这使得它在现实生活场景中完全没用。 如果您只想记录您的异常,您应该在leas log错误消息。 另外,您可能需要不同的行为,或者您希望在代码中的不同位置处理不同的异常。因此异常类型可能非常有用。

  

那么这两种不同类型的错误如何与同一代码块一起使用   很简单,所有例外情况都是在层次结构中进行组织,在您的情况ArithmeticException中,由#next翻译为' nextInt'方法扩展Exception

如果您想查看更多异常层次结构,请查看此图片enter image description here

答案 6 :(得分:0)

回答标题问题:

您可以使用抛出的e例外来帮助您诊断问题:

try {
    ...
} catch (Exception e) {
    System.out.println("Thrown exception: " + e.getMessage());
    //OR, for a custom error
    throw new Exception("Error in try block", e);
}

回答您的第二个问题:

Java中的所有异常都来自基本的Exception类型,因此拥有catch(Exception e)将捕获try块中抛出的所有异常。

您可以拥有多个catch块来处理不同的错误:

try {
    ...
} catch (ArithmeticException ae) {
    System.out.println("This was an arithmetic exception.");
} catch (IOException ioe) {
    System.out.println("This was an I/O exception.");
}

但是除非您使用抛出的catch (Exception e)例外,否则通用e不会为您提供任何有用的诊断数据:

try {
    ...
} catch (Exception e) {
    System.out.println("Thrown exception: " + e.getMessage());
}