我在处理异常时遇到过一个场景,下面是示例代码。我试图理解为什么以下代码无法编译。我在重新抛出之前检查异常类型,这是未经检查的异常。
public class TestException {
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args){
TestException test=new TestException();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}
答案 0 :(得分:1)
您仍然在抛出e
类型的引用变量Exception
。 Exception
是已检查类型。编译器只知道引用变量的类型,而不是引用的对象。如果您希望按原样保留main
方法签名,则需要将e
包装到未经检查的异常类型(例如ArithmeticException
)中:
if(e instanceof ArithmeticException){
throw new ArithmeticException(e.getMessage());
}
或将其转换为未经检查的例外:
if(e instanceof ArithmeticException){
throw (ArithmeticException)e;
}
答案 1 :(得分:1)
由于引用变量e
的类型为java.lang.Exception
,throw e
将抛出已检查的异常。因此,必须在方法签名的throws
部分中声明它。
答案 2 :(得分:0)
我建议使用两个catch块。 catch块中的类型检查不是一个很好的做法,你可以使用其他catch语句捕获该特定的类。
catch (ArithmeticException e) {
// TODO Auto-generated catch block
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
@Silly Freak我同意你的看法。
答案 3 :(得分:0)
您还可以使用Generics的hack将已检查的Exception作为未经检查的Exception:
我喜欢在throw new RuntimeException(e)
上使用它,因为后者在Stacktrace中创建了不必要的输出,并且更难以捕捉到其他地方(你必须检查原因而不是检查本身)。
答案 4 :(得分:0)
catch (Exception e) {
以下是e
的有效声明。
if(e instanceof ArithmeticException){
您正在执行运行时检查e.
的类型
throw e;
此时编译时类型e
为Exception
。因此编译器会强制执行其规则。
答案 5 :(得分:-1)
如果你抛出任何异常然后你应该处理它但是在你的程序中你可以抛出但是你无处处理异常,所以只需在主类中添加throws
来处理异常,如下所示: - < / p>
package first;
import java.io.FileNotFoundException;
import java.io.FileReader;
class A3{
public void test() throws FileNotFoundException {
FileReader test = new FileReader("");
}
public static void main(String[] args) throws Exception{
A3 test=new A3();
try {
test.test();
} catch (Exception e) {
// TODO Auto-generated catch block
if(e instanceof ArithmeticException){
throw e;
}
else{
e.printStackTrace();
}
}
}
}