自定义的 RuntimeException 未捕获 java.lang.ArrayIndexOutOfBoundsException

Customized RuntimeException not catching java.lang.ArrayIndexOutOfBoundsException

任何人都可以说出为什么 catch close 正在回避(不捕获)ArrayIndexOutOfBoundsException 吗? catch 块仅适用于没有自定义异常的情况。

class MyException extends RuntimeException {

    public MyException(String msg) {

        super(msg);
        System.out.println("caught in MyException2 constructor");
    }
}

public class CustomizedExceptionTester {

        public static void main(String[] args) {
            try {
                doTest();
            } catch (MyException me) {

                System.out.println("caught in catch block");

                System.out.println(me);
            }
        }

        static void doTest() throws MyException {
            int[] array = new int[10];
            array[10] = 1000;
        }
    }

打印:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at oca.exceptions.InterfaceWithException.doTest(InterfaceWithException.java:32)
    at oca.exceptions.InterfaceWithException.main(InterfaceWithException.java:17)

为什么你会期望它?你在 catch 块中有 MyException;它只会捕获该类型的异常。尽管 MyExceptionArrayIndexOutOfBoundsException 都扩展了 RuntimeException,但这并不意味着当您指定 any 子类;只会捕获指定的类型。

这样想。假设我有 "four-sided shape"、"rectangle" 和 "rhombus"。如果我说"catch any rectangles I throw you",你会抓到菱形吗?但是,如果我说 "catch any four-sided shape I throw you",你无论如何都会抓住。

你是说 doTest() 可以抛出 MyException ,无论是否抛出都很好。尝试越界访问数组索引不会抛出 MyException,而是抛出 ArrayIndexOutOfBoundsException。 Java 不会捕获未抛出的异常。如果你想让你的自定义异常代码 运行 需要显式抛出它。

try {
    array[10] = 1000;
} catch (ArrayIndexOutOfBoundsException e) {
    throw new MyException(e.getMessage());
}

这种情况并没有真正从中受益,因此您可以将异常代码移到 catch 块内或将其提取到单独的方法中。