Java 中的已检查和未检查异常,这些断言是否正确?

Checked and unchecked exception in Java, are these assertions true?

我对checked exceptionunchecked exception之间的区别有一些疑问。

我知道 checked exception 通常表示 程序直接控制之外的区域中的无效条件 例如无效的用户输入、数据库问题、网络中断、文件丢失等

我也知道 checked exceptionException 抽象 class 的子class 并且 一个方法有义务为其实现抛出的所有已检查异常建立一个策略(要么将已检查异常进一步向上传递到堆栈,要么以某种方式处理它)。

那么,在实践中,最后一个断言究竟意味着什么?

我可以简单地说 已检查的异常 在编译时检查。这意味着如果一个方法抛出一个检查异常,那么它应该使用 try-catch 块处理异常,或者它应该使用 throws 关键字声明异常,否则程序会报编译错误。它被命名为检查异常,因为这些异常是在编译时检查的。

所以,如果一个方法抛出 checked exception 我可以用两种不同的方式处理它:

  1. 我必须将它处理成一个 try-catch 块,像这样:

    try{
        //statements that may cause an exception
    } catch (exception(type) e(object))‏ {
        //error handling code
    }
    
  2. 使用方法声明中使用的 throws 关键字,以明确指定特定方法可能抛出的异常。当方法声明有一个或多个使用 throws 子句定义的异常时,方法调用必须处理所有定义的异常。

    所以,如果我说错了断言,请纠正我,throws 关键字用于 将检索到的已检查异常抛出到堆栈的上层(进入来电)。因此,如果一个方法调用另一个 throw 检查异常的方法,如果它被抛出,调用方方法必须处理它(例如通过 try catch 堵塞)。这个推理对吗?

    那么 checked exceptions 是否存在引入一种 紧耦合 形式的缺点,因为如果我有一个链方法和最后一个 throws 已检查的异常或我将其处理到其父代码中或所有中间方法必须通过 throws[=88= 声明异常] 方法声明中的关键字?这个说法正确吗?

相反,未经检查的异常 在编译时不检查。这意味着如果您的程序抛出未经检查的异常,即使您没有 handle/declare 该异常,程序也不会给出编译错误。大多数情况下,这些异常的发生是由于用户在用户程序交互期间提供的错误数据。由程序员提前判断可能导致此类异常的条件并适当地处理它们。所有未经检查的异常都是 RuntimeException class.

的直接子 classes

例如我可以遇到这样的情况:

class Example {  
   public static void main(String args[])
   {
    int num1=10;
    int num2=0;
    /*Since I'm dividing an integer with 0
     * it should throw ArithmeticException*/
    int res=num1/num2;
    System.out.println(res);
   }
}

编译这个 class 编译器没有给我错误但是 运行 我会得到一个 ArithmeticException tath 是一个 unchecked exception 因为它发生在运行时。

所以我认为是开发人员必须处理这种情况,做如下事情:

class Example {  
   public static void main(String args[])
   {
    int num1=10;
    int num2=0;
    /*Since I'm dividing an integer with 0
     * it should throw ArithmeticException*/
    try {
        int res=num1/num2;
    } catch(ArithmeticException e) {
         System.out.println("Division for 0, this is not a good idea !!!");
    }

    System.out.println(res);
   }
}

所以我的疑惑是:

  1. 在我看来,我也可以将 try catch 块用于 未经检查的异常 。那么 try catch 块在 checked exceptionunchecked exception 之间的使用有什么区别?是否只有 checked exception 我必须使用它(或在方法声明中使用 throws 关键字)否则我将获得编译时间错误信息?

  2. 未经检查的异常是否也自动传播到上层进入方法调用的堆栈?

Tnx

  1. 是的。您可以使用 try catch 块来捕获未经检查的异常以及已检查的异常。

  2. 所有异常,无论是已检查还是未检查,如果未被捕获,都会传播到下一级。

不同之处在于,如果一个方法可以抛出一个已检查的异常E(要么是因为它调用了一个throws E的方法,要么是因为它直接用语句throw E抛出它自己) 方法声明必须使用 throws E.

包含此信息

因此,如果你想调用一个可以抛出检查异常的方法 E 必须 要么将方法调用放在 try 块中,要么声明 throws E。这些东西对于未经检查的异常是可选的。

大多数时候你不应该捕获未经检查的异常。

关于 throws 引入的耦合,你完全正确:在 throws 子句中声明的异常成为方法的 public 接口的一部分(一般意义上的词;不考虑 Java 的接口和 public 访问)。但是,这种耦合与通过声明方法的 return 类型或参数类型引入的耦合没有什么不同。您可以将其视为方法签名的第三个属性。

It seems to me that I can use the try catch block also for the unchecked exception. So what is the difference in the use of try catch block that exist between checked exception and unchecked exception?

您当然可以捕获未经检查的异常,但您应该在程序的最顶层执行此操作以防止完全崩溃。未经检查的异常表示编程错误,因此您无法以有意义的方式处理它们。你能做的最好的事情就是记录它们,然后继续。

Also the unchecked exception are automatically propagated to the superior level into the stack of the methods call?

是的,他们这样做的方式与在 throws 子句中声明异常但未捕获异常时检查异常的方式相同。

  1. 未检查异常和已检查异常的try catch没有区别。正如你所说。

    -如果一个方法使用另一个可能抛出检查异常的方法,则以下两个条件之一应该为真: 该方法应包含在 try-catch 块中,或者该方法应在其方法签名中指定要抛出的异常。

    -未经检查的异常可能不是方法签名的一部分,即使 方法可能会抛出它。

  2. 当一段代码以异常条件的形式遇到障碍时,它会创建一个classjava.lang.Throwable的对象。已检查和未检查异常通过方法调用传播,因为它们都是 subclass java.lang.Throwable.