在代码片段1中,方法m1()在throws声明中有SQLException,但实际上它抛出了一个类型为
Exception
的引用变量。我原本以为会出现编译器错误,因为throws
声明中没有提到Exception
。但是它可以编译并打印Caught successfully
。import java.sql.SQLException;
public class Snippet1{
private static void m() throws SQLException{
try{
throw new SQLException();
} catch(Exception e){
throw e;
}
}
public static void main(String[] args){
try{
m();
} catch(SQLException e){
System.out.println("Caught successfully"); //prints "Caught successfully
}
}
}
代码片段2与前一个示例几乎相同,唯一的区别在于我们将null
分配给异常引用变量e
,然后抛出它。现在编译器会提示 Exception
必须被捕获或声明抛出。
import java.sql.SQLException;
public class Snippet2{
private static void m() throws SQLException{
try{
throw new SQLException();
} catch(Exception e){
e = null;
throw e;
}
}
public static void main(String[] args){
try{
m();
} catch(SQLException e){
System.out.println("Caught successfully");
}
}
}
我不理解为什么 #1 可以编译而 #2 不能。
FirstException
、SecondException
...或未经检查的异常。重点是catch(Exception e){throw e;}
可以捕获并重新抛出(例如)NullPointerException
。就JLS而言,这是可以接受的。 - Stephen C