Java catch子句内抛出异常

Java catch子句内抛出异常,java,exception-handling,Java,Exception Handling,我有两段代码: class PreciseRethrow { public static void main(String[] str) { try { foo(); } catch (NumberFormatException ife) { System.out.println(ife); } } static private void foo() throws NumberFormatException { try {

我有两段代码:

class PreciseRethrow {
public static void main(String[] str) {
    try {
        foo();
    } catch (NumberFormatException ife) {
        System.out.println(ife);
    }
}

static private void foo() throws NumberFormatException {
    try {
        int i = Integer.parseInt("ten");
    } catch (Exception e) {
        throw e;
    }
}
}
以及:


在第二种情况下,当我在catch子句中抛出新的异常()时,我得到了编译错误“Unhandled exception type exception”。你能解释一下为什么在第一种情况下一切正常,但在第二种情况下我得到编译错误吗?在这两种情况下,我都抛出异常,但在第二种情况下,我创建了新的异常实例(这两个示例之间的唯一区别)。谢谢您的帮助。

在第一个代码片段中,您正在抛出可能出现的
NumberFormatException
。在第二个代码段中,您只抛出了常规的
异常
,而不是该方法所声明的
NumberFormatException

您试图抛出一个异常,但是您声明将抛出一个
NumberFormatException
,它是
异常
的子类型。所有
NumberFormatException
s都是
Exception
s,但并非所有
Exception
s都是
NumberFormatException
,因此它是不允许的。然而,在第一个示例中,虽然您捕获了一个
异常
,但编译器和IDE知道它将永远只是一个
数字格式异常
,这是安全的。

不同之处在于,编译器可以看到,在第一个示例中,唯一可以重新调用的选中异常是
NumberFormatException
。(您没有创建任何新的异常。)因此,它对头中的
抛出NumberFormatException{
声明感到满意


但是,在第二个示例中,您显式地抛出了一个未在头中声明的已检查异常,因此可以预见会出现编译器错误。

编译器可以确定在
抛出e
的情况下,它只能是一个已在thro中声明的
NumberFormatException
类型的已检查异常ws子句


在后一种情况下,您试图抛出选中的
异常
,该异常需要在throws子句中声明或捕获。

这里,您从catch块抛出新的异常(),但您已经提到您的方法foo()只能抛出层次结构中较低的NumberFormatException()

   static private void foo() throws NumberFormatException {
    try {
    int i = Integer.parseInt("ten");
   } catch (Exception e) {
    throw new Exception();
   }
  }

首先:您的第一个示例也不是用Java 6编译的。但是,由于异常处理的新特性,它将用Java 7编译

请参阅以了解更多信息。基本上,从Java 7开始,编译器可以更精确地分析从
try
块抛出的异常;即使捕获一个或多个抛出异常的超类并按原样重新抛出(即,没有强制转换),编译器也不会抱怨。但是,Java 6及更早版本会抱怨

然而,在第二个示例中,您重新引用了
异常的新的实例。实际上,这与签名不匹配

总而言之,这意味着使用Java 7可以做到这一点,但使用Java 6不行:

public void someMethod()
    throws MyException
{
    try {
        throw new MyException();
    } catch (Exception e) { // Note: Exception, not MyException
        throw e;
    }
}
Java 6只看到catch参数的类型为
Exception
;对于Java 6,这与方法签名-->编译错误不匹配

Java 7发现try块只能抛出
MyException
。因此,方法签名匹配-->没有编译错误


但不要这样做;)这相当令人困惑…

在这两种情况下,编译时错误都会出现。因为您试图抛出一个名为exception的选中异常。 你必须做两件事中的一件:

在catch块中使用try构造 或
在foo()的throws子句中添加Exception()

解释得很好,特别是当我得出结论时,我只是在阅读了@fge之后才理解这一点。java6和java7之间的差异。但是good@prash:你忘记实际投票了吗?是的!事实上我是通过手机投票的。请求没有完成。3g非常低。现在就投票了。谢谢。@Keppil
public void someMethod()
    throws MyException
{
    try {
        throw new MyException();
    } catch (Exception e) { // Note: Exception, not MyException
        throw e;
    }
}