Java 例外情况不存在';不需要抛出才能被捕获,但IOException确实需要

Java 例外情况不存在';不需要抛出才能被捕获,但IOException确实需要,java,exception,throws,Java,Exception,Throws,为什么下面的代码编译得很好,但是被调用的方法不需要抛出异常?异常不是已检查的异常而不是未检查的异常吗?请澄清 class App { public static void main(String[] args) { try { amethod(); System.out.println("try "); } catch (Exception e) { System.out.print(

为什么下面的代码编译得很好,但是被调用的方法不需要抛出异常?
异常
不是已检查的异常而不是未检查的异常吗?请澄清

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (Exception e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() { }
}
如果我想对
IOexception
(选中的异常)使用try-catch,则调用的方法需要抛出
IOexception
。我明白了

import java.io.IOException;

class App {
    public static void main(String[] args) {
        try {
            amethod();
            System.out.println("try ");
        } catch (IOException e) {
            System.out.print("catch ");
        } finally {
            System.out.print("finally ");
        }
        System.out.print("out ");
    }
    public static void amethod() throws IOException { }
}
“异常”不是已检查的异常,不是未检查的异常吗

是的

但是,即使我们知道该方法不会抛出
Exception
本身,代码
catch(Exception e){
仍然可以执行。
try
块中的代码仍然可以抛出从
Exception
继承的内容。其中包括
RuntimeException
及其未选中的子类


另一方面,
catch(IOException e){
只能捕获检查过的异常。(Java不允许多重继承,因此任何属于
IOException
的子类都不可能是
RuntimeException
的子类)编译器可以相当容易地找出
try
块中的任何代码都不可能抛出
IOException
(因为任何抛出选中异常的方法都必须明确地这样说)这允许它标记代码。

您观察到的行为来自以下事实,即Java语言规范在这种情况下特别处理
异常

如果catch子句可以捕获选中的异常类E1,并且与
catch
子句对应的
try
块不会抛出作为E1的子类或超类的选中异常类,则这是编译时错误,除非E1是
exception
exception
的超类


这是合理的,因为
异常
(及其超类
可丢弃
)也可用于捕获扩展
RuntimeException
的异常。由于运行时异常总是可能的,编译器总是允许
异常
出现在
catch
子句中,而不管是否存在选中的异常。

我认为您的理解是错误的。
抛出
声明用于列出被调用方将抛出的已检查异常,而不是调用方将捕获的异常。完美!易于理解