Java未处理异常消失

Java未处理异常消失,java,exception,try-catch-finally,Java,Exception,Try Catch Finally,假设有这样一个类: public class Magic { public static void main(String[] args){ boolean[] val = new boolean[0]; paradox(val); } private static boolean paradox(boolean[] arg) { Container container = null; try { container = Container.g

假设有这样一个类:

public class Magic {

public static void main(String[] args){
    boolean[] val = new boolean[0];
    paradox(val);
}

private static boolean paradox(boolean[] arg) {
    Container container = null;
    try {
        container = Container.getContainer(arg[0]);
        return container.value;
    } catch (UnsupportedOperationException e) {
        e.printStackTrace();
        return false;
    } finally {
        try {
            container.sayHi();
        } catch (UnsupportedOperationException e) {
            e.printStackTrace();
        }
    }
}

private static class Container{
    private boolean value;

    private Container(boolean value){
        this.value = value;
    }

    private static Container getContainer(boolean value) throws UnsupportedOperationException{
        return new Container(value);
    }

    private void sayHi(){
        System.out.println("Hi!");
    }
}
}
如果执行此代码,则在

container.sayHi();
容器
实际上应该为空。在分配完成之前,调用getContainer()时会引发ArrayIndexOutOfBoundException。但是,ArrayIndexOutOfBoundException会发生什么情况?为什么在一个未处理的异常之后要进入finally{}

编辑:措辞不当。问题是为什么我们直接进入最后{}。ArrayIndexOutOfBoundException会发生什么

为什么在一个未处理的异常之后要进入finally{}

在块退出后(成功、异常处理程序之后或未处理的异常之后),我们总是转到
finally
。这正是
的最终目的:放置无论发生什么都将运行的代码

但是,ArrayIndexOutOfBoundException会发生什么情况

如果在异常处理程序或
finally
块中遇到第二个异常,则会传播第二个异常,并隐藏原始异常

如果要保留原始异常,可以通过手动将其附加到新异常(或者反过来,重新抛出原始异常并将新异常附加为抑制)

为什么在一个未处理的异常之后要进入finally{}

在块退出后(成功、异常处理程序之后或未处理的异常之后),我们总是转到
finally
。这正是
的最终目的:放置无论发生什么都将运行的代码

但是,ArrayIndexOutOfBoundException会发生什么情况

如果在异常处理程序或
finally
块中遇到第二个异常,则会传播第二个异常,并隐藏原始异常


如果要保留原始异常,可以通过手动将其附加到新异常(或者反过来,重新抛出原始异常并将新异常附加为已抑制)。Java中有一个简单的规则:
最终
始终调用。1

那么发生的情况是:

container = Container.getContainer(arg[0]);
这将抛出一个未捕获的
ArrayIndexOutOfBoundException
。在异常冒泡之前,
最终被调用

container.sayHi();
container==null
因此会抛出
NullPointerException
,这会隐藏原始异常。按照

如果try块的执行由于抛出值V而突然完成,则有一个选择

。。。然后

如果finally块因原因S而突然完成,则try语句因原因S而突然完成(并且值V的抛出被丢弃并被遗忘)

重点矿山


1:除非调用了
System.exit
或其他罕见情况。

Java中有一个简单的规则:
最后
总是被调用。1

那么发生的情况是:

container = Container.getContainer(arg[0]);
这将抛出一个未捕获的
ArrayIndexOutOfBoundException
。在异常冒泡之前,
最终被调用

container.sayHi();
container==null
因此会抛出
NullPointerException
,这会隐藏原始异常。按照

如果try块的执行由于抛出值V而突然完成,则有一个选择

。。。然后

如果finally块因原因S而突然完成,则try语句因原因S而突然完成(并且值V的抛出被丢弃并被遗忘)

重点矿山


1:除非调用了
System.exit
或其他罕见情况。

在finally块中执行控制流操作时,您可能会遇到另一个意外情况:

public static void main(String[] args) {
    System.out.println(badFunction());
}

private static String badFunction() {
    try {
        throw new RuntimeException("Catch it!");
    } finally {
        return "Exception disappears";
    }
}

在finally块中执行控制流操作时,您可能会遇到另一个惊喜:

public static void main(String[] args) {
    System.out.println(badFunction());
}

private static String badFunction() {
    try {
        throw new RuntimeException("Catch it!");
    } finally {
        return "Exception disappears";
    }
}

问题是如何访问
中的原始异常。最后,这是正确的。下面是如何为try with resources结构的自动生成的finally块实现的:第一条业务规则可能是确保
finally
一开始就不会引发任何异常。问题是如何在
finally
中访问原始异常。下面是如何为try with resources结构的自动生成的finally块实现的:业务的第一条规则可能是确保
finally
一开始不会引发任何异常。是的,
finally{}
应该总是顺利完成。(除了无法防止的抛出错误)是的,
最后{}
应该总是平稳地完成。(除了无法避免的投掷错误)