【问题标题】:Checked Unchecked Exceptions已检查未检查异常
【发布时间】:2009-07-10 04:08:44
【问题描述】:

考虑下面的代码

private int meth()
{
   try
   {
       return 1;
   }
   catch(Exception ex)
   {
       return 2;
   }
   finally
   {
       return 3;
   }
}

编译上述代码时,“异常”被视为未经检查的异常。那就是“尝试块中永远不会抛出无法到达的catch块异常”编译错误不会发生。考虑我声明自己的异常,

class MyException extends Exception
{
}

并在代码中使用它

private int meth()
{
   try
   {
      return 1;
   }
   catch(MyException me)
   {
      return 2;
   }
   finally
   {
      return 3;
   }
}

在这个“unreachable catch block MyException is never throw in try block”中发生编译错误。为什么在第一种情况下“异常”被视为 RuntimeException 而在第二种情况下,即使“MyException”是“异常”的子类,它也被视为已检查异常。有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: java exception


    【解决方案1】:

    这种行为的原因是 Java 语言中唯一未经检查的异常是 RuntimeException 及其子类。所有其他异常和错误,包括您的,因为它仅子类 Exception(而不是 RuntimeException)是检查异常。

    第一个代码示例没有被编译器标记,尽管它使用 Exception 类作为其 catch 语句的原因是因为类层次结构。由于所有异常都派生自 Exception,因此您的代码不是专门捕获 Exception,而是捕获所有异常并将它们转换为 Exception 的实例。因此,编译器无法判断将在运行时捕获的异常是已检查异常还是未检查异常。在第二个代码块中,捕获的异常不可能不是已检查异常,因此编译器可以确定您的 catch 块不可达。

    【讨论】:

    • +1 - 我正要写那个...看看异常继承层次结构...它都在那里:-)
    【解决方案2】:

    就编译器所知,您在任何时候都可能遇到堆栈溢出异常、内存不足异常、算术异常或任何数量的其他 JVM 生成的异常。另一方面,它可以静态分析try 块并看到MyException 从未被抛出,因此它举起手来。它知道它永远不会被 JVM 抛出。

    【讨论】:

    • 这是我的猜测——因为它将 JVM 异常视为可以抛出的异常——但它知道除非有“抛出”调用,否则不能抛出用户定义的异常尝试中的任何地方。
    【解决方案3】:

    在 Java 中,未检查 (RuntimeExceptions) 和已检查异常都派生自 Exception。

    在您的示例中,在第一种情况下,catch 块可以要么 捕获 RuintimeException(您在这里得到怀疑)或任何已检查的异常,因此不要抱怨未捕获的异常。

    但是,在第二种情况下,因为您明确提到了一种已检查的异常类型,并且不会在代码的任何部分中抛出,因此会出错。 此 catch 块不适用于 RTExceptions。在这种特殊情况下,您不必怀疑在您的第一个场景中使用了哪个编译器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多