考虑以下代码
private int meth()
{
try
{
return 1;
}
catch(Exception ex)
{
return 2;
}
finally
{
return 3;
}
}
编译上述代码时,“Exception”被视为未经检查的异常。那就是“无法访问的catch块异常永远不会在try块中抛出”编译错误不会发生。考虑我自己声明异常,
class MyException extends Exception
{
}
并在代码中使用它
private int meth()
{
try
{
return 1;
}
catch(MyException me)
{
return 2;
}
finally
{
return 3;
}
}
在这个“无法访问的catch块中,MyException永远不会在try块中抛出”发生编译错误。为什么在第一个场景中“异常”被视为RuntimeException,而在第二个场景中,即使“MyException”是“Exception”的子类,它也被视为已检查的异常。有人可以帮我解决这个问题吗?
答案 0 :(得分:12)
此行为的原因是Java语言中唯一未经检查的异常是RuntimeException及其子类。所有其他异常和错误,包括你的,因为它只是子类Exception(而不是RuntimeException)是被检查的异常。
第一个代码示例未被编译器标记的原因,尽管它使用Exception类作为其catch语句,这是因为类层次结构。由于所有异常都是从Exception派生的,因此您的代码并没有特别捕获Exception,而是捕获所有异常并将它们转换为Exception实例。因此,编译器无法判断将在运行时捕获的异常是已检查还是未检查的异常。在第二个代码块中,没有办法使捕获的异常不是一个已检查的异常,因此编译器可以确定您的catch块无法访问。
答案 1 :(得分:4)
就编译器而言,您可以在任何时候获得堆栈溢出异常,内存不足异常,算术异常或任何其他JVM生成的异常。另一方面,它可以静态分析try
块,并看到MyException
永远不会被抛出,所以它会举起手来。它知道它永远不会被JVM抛出。
答案 2 :(得分:1)
在Java中,未经检查(RuntimeExceptions)和已检查的异常都来自异常。
在您的示例中,在第一种情况下,catch块可以 捕获RuintimeException(您在此处获得怀疑)或任何已检查的异常,因此不会抱怨未捕获的异常。
但是在第二种情况下,因为您已经明确提到了一个被检查的异常类型,并且没有在代码的任何部分抛出,因此会出错。 此catch块不适用于RTExceptions。在这种特殊情况下,您无法怀疑编译器在第一个场景中遇到的问题。