![](/img/trans.png)
[英]Why i can`t throw Exception(checked) in a method that is invoked in a try catch statement?
[英]Why can't I handle Exception e with try / catch clause?
当我编译以下代码时,一切正常,并且输出符合预期:
class Propogate {
public static void main(String[] args) {
Propogate obj = new Propogate();
try {
obj.reverse("");
} catch (IllegalArgumentException e) {
System.out.println(e);
} finally {
System.out.println("That's all folks");
}
}
String reverse(String s) {
if(s.length() == 00) {
throw new IllegalArgumentException();
}
String reversed = "";
for(int i=s.length() - 1; i >= 0; --i) {
reversed += s.charAt(i);
}
return reversed;
}
}
程序结果:
java.lang.IllegalArgumentException
That's all folks
但是,当我运行完全相同的代码但将异常类型从
IllegalArgumentException to plain old exception all I get is:Propogate.java:14: error:
unreported exception Exception; must be caught or declared to be thrown
throw new Exception();
^
1 error
父类型Exception()的特殊之处是我无法使用try / catch语句来处理它? 为什么IllegalArgumentException()允许我使用try / catch语句来很好地处理它。 这些就是晚上参加SCJP考试时会因失败而害怕的恐惧而保持清醒的想法。
抛出不是RuntimeException
的子类的异常的方法必须声明它抛出该Exception
。 你必须写
String reverse(String s) throws Exception {
如果您要抛出一个Exception
。 完成此操作后,您可以正常尝试/捕获它。
IllegalArgumentException
是未经检查的异常,因为它们是RuntimeException
子类。 因此,编译器不会检查它们。 编译器会检查非RuntimeException
对象(例如Exception
,这将解释您所看到的内容。
因为您正在main()
捕获异常,这是调用堆栈的底部,所以我认为最好使用catch (Exception e)
来覆盖所有意外catch (Exception e)
。
引发作为RuntimeException的子类的异常的方法不必声明在该方法之后立即引发该Exception。 这就是为什么第一个代码运行良好的原因。
但是,将异常类型更改为Non-RuntimeException时,必须使该方法引发Exception,否则将发生编译错误。 这就是第二个代码出错的原因。
其他答案涵盖了编译器为什么不满意的原因,以及您可以采取的措施。 但是我认为您真正的错误是首先抛出Exception
。
抛出Exception
几乎总是一个坏主意。 原因是,如果您的代码抛出Exception
,则它(或其他人的代码)通常必须捕获该异常。 但是捕获Exception
的问题是您的代码还捕获了您的代码可能抛出的Exception
所有子类型。 包括未经检查的异常,这些异常可能是由代码中的错误等引起的。
例如:
public class Test {
private static Integer a;
private static Integer b;
public static void main(String[] args) {
try {
if (a.equals(b)) {
throw Exception("they are the same");
}
System.out.println("they are different");
} catch (Exception ex) {
System.out.println(ex.message());
}
}
}
运行此命令时,将得到神秘的输出“ null”。 (供读者练习……准确地找出原因。)
将方法声明为throws Exception
更加糟糕,因为现在调用者被迫捕获Exception
(不良)或传播Exception
(更糟)。 声明为throws Exception
方法就像癌症。
将main
方法声明为throws Exception
是一个特例。 JVM基础结构通常调用主要方法,该方法旨在处理任何异常。 它只是将stacktrace打印到标准错误。 即使这样,自己处理异常可能也更整洁。 在“生产级”代码库中,您通常希望将意外的异常记录在错误日志中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.