JDK 1.7 之后,从 catch 块中抛出异常对象不需要 throws 子句!!!为什么会这样?
JDK 1.7 onwards, throwing an exception object from catch block does not require a throws clause!!! Why is this so?
我今天在 java 编码时遇到了一个奇怪的场景。我的方法中有一个 try..catch 块,它没有任何 throws 子句,我能够抛出在 catch 块中捕获的异常对象。 它是异常 class 的对象,因此它不是未经检查的异常。 此外,如果出现异常,它不会打印堆栈跟踪,而是异常会被吞噬。
下面是我的代码示例,
public class ExceptionTest {
public void test() {
try
{
// Some code which may throw exception.
}
catch(Exception ex)
{
// Compiler should ask me to have a *throws Exception* in the signature, when I am throwing an exception object.
throw ex;
}
}
}
但是,如果我抛出一个新的异常对象而不是捕获的异常对象,编译器会要求我在方法签名中有一个 throws 子句。
N.B: I am facing this situation when running in Java 7 or 8.
我想知道,抛出的物体要去哪里?任何对此有任何想法的人请...
如果 try
块中的代码不能抛出任何 checked 异常,您就会看到这一点。那时,编译器知道 catch
块捕获的唯一异常必须是未经检查的异常,因此可以重新抛出它。请注意,如果您在 catch
块中为 ex
分配了不同的值,则编译器将无法再获得该保证。目前,ex
有效最终。
如果您尝试调用在 try
块中声明为抛出检查异常的内容,代码将无法按预期编译。
例如:
public class ExceptionTest {
public void test() {
try {
foo();
} catch(Exception ex) {
throw ex;
}
}
public void foo() throws java.io.IOException {
}
}
给出错误:
ExceptionTest.java:12: error: unreported exception IOException; must be caught or declared to be thrown
throw ex;
^
至于异常在哪里 "goes" - 如果 try 块中的代码抛出未经检查的异常,它会正常传播。试试这个:
public class ExceptionTest {
public static void main(String[] args) {
test();
}
public static void test() {
try {
String x = null;
x.length();
} catch(Exception ex) {
throw ex;
}
}
}
运行 按预期提供以下输出:
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.test(ExceptionTest.java:10)
at ExceptionTest.main(ExceptionTest.java:4)
JLS 11.2.2 记录语句可以抛出哪些异常 - 只有在没有可以抛出的已检查异常时,您的代码才会编译。
请检查您是否真的在代码中抛出异常。否则编译器不会关心捕获异常。
public class ExceptionTest {
public void test() {
try
{
throw new Exception("Error");
}
catch(Exception ex)
{
// My Compiler says that I don't catch the exception
throw ex;
}
}
}
编译器:错误:(14、13)java:未报告的异常java.lang.Exception;必须被捕获或声明被抛出
我今天在 java 编码时遇到了一个奇怪的场景。我的方法中有一个 try..catch 块,它没有任何 throws 子句,我能够抛出在 catch 块中捕获的异常对象。 它是异常 class 的对象,因此它不是未经检查的异常。 此外,如果出现异常,它不会打印堆栈跟踪,而是异常会被吞噬。
下面是我的代码示例,
public class ExceptionTest {
public void test() {
try
{
// Some code which may throw exception.
}
catch(Exception ex)
{
// Compiler should ask me to have a *throws Exception* in the signature, when I am throwing an exception object.
throw ex;
}
}
}
但是,如果我抛出一个新的异常对象而不是捕获的异常对象,编译器会要求我在方法签名中有一个 throws 子句。
N.B: I am facing this situation when running in Java 7 or 8.
我想知道,抛出的物体要去哪里?任何对此有任何想法的人请...
如果 try
块中的代码不能抛出任何 checked 异常,您就会看到这一点。那时,编译器知道 catch
块捕获的唯一异常必须是未经检查的异常,因此可以重新抛出它。请注意,如果您在 catch
块中为 ex
分配了不同的值,则编译器将无法再获得该保证。目前,ex
有效最终。
如果您尝试调用在 try
块中声明为抛出检查异常的内容,代码将无法按预期编译。
例如:
public class ExceptionTest {
public void test() {
try {
foo();
} catch(Exception ex) {
throw ex;
}
}
public void foo() throws java.io.IOException {
}
}
给出错误:
ExceptionTest.java:12: error: unreported exception IOException; must be caught or declared to be thrown
throw ex;
^
至于异常在哪里 "goes" - 如果 try 块中的代码抛出未经检查的异常,它会正常传播。试试这个:
public class ExceptionTest {
public static void main(String[] args) {
test();
}
public static void test() {
try {
String x = null;
x.length();
} catch(Exception ex) {
throw ex;
}
}
}
运行 按预期提供以下输出:
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.test(ExceptionTest.java:10)
at ExceptionTest.main(ExceptionTest.java:4)
JLS 11.2.2 记录语句可以抛出哪些异常 - 只有在没有可以抛出的已检查异常时,您的代码才会编译。
请检查您是否真的在代码中抛出异常。否则编译器不会关心捕获异常。
public class ExceptionTest {
public void test() {
try
{
throw new Exception("Error");
}
catch(Exception ex)
{
// My Compiler says that I don't catch the exception
throw ex;
}
}
}
编译器:错误:(14、13)java:未报告的异常java.lang.Exception;必须被捕获或声明被抛出