我正尝试两次处理异常
第一个是已定义方法的核心:
Class Class1 {
public int method (int a, String b) {
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
}
finally {
System.out.println("finally from the method");
}
return 0;
}
}
第二个
是当我在main中调用此方法并将空参数传递给它时:
public Class Class2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Class1 c = null;
try {
c = new Class1();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
c.method(1, null);
}
catch (Exception e) {
// TODO: handle exception
System.out.println("catch from the main");
}
finally {
System.out.println("finally from the main");
}
System.out.println("\nEnd of the main");
}
}
结果是:
从方法
捕获最后是方法
最终从主要方面
主体末端
现在我的问题是,为什么主程序中的catch块没有执行?
答案 0 :(得分:3)
一旦捕获到异常,它就不会继续存在,但是您可以再次抛出它。如果您希望主对象也看到异常,则需要在捕获到异常后再次抛出该异常。试试这个:
public int method (int a, String b) throws NullPointerException{
try {
System.out.println(a+" "+b.length());
}
catch (NullPointerException e) {
// TODO: handle exception
System.out.println("catch from the method");
throw e;
}
finally {
System.out.println("finally from the method");
}
return 0;
}
请注意,由于该函数现在引发了异常,因此您需要将其包含在函数定义中
编辑:正如几个人所说,NullPointerException确实不需要捕获,因为它是未经检查的异常。这是因为它是RuntimeException的子类。
答案 1 :(得分:1)
您会找到许多有关引发和捕获异常机制的文章。我发现更重要的是如何充分利用异常概念。
这并不完全是您的问题的答案,但也许可以澄清当前情况背后的一些概念。
如果某个方法完成了其工作,则应正常返回。如果这样做失败,则应引发异常而不是正常返回。从您的方法中产生的异常应该包含有关该问题的信息(大多数标准异常已经做得很好)。
在从属方法中,通常不应使用try / catch。如果出现问题(方法中出现一些异常),则您的方法通常无法完成其工作,它应该通过异常来告知调用方,最简单的方法就是让异常通过。 p>
在顶层方法(例如,主菜单,主菜单操作,单击按钮的操作)中,捕获所有异常,通知用户(可能是管理员),然后继续(如果可能/适当)。 / p>
如果您的方法遇到一个异常(例如NullPointerException),并希望向其调用方显示另一个异常,请捕获该异常,使用原始的cause
创建所需的新异常,并抛出这个新异常。我个人希望尽量避免这种“例外翻译”。
如果必须关闭体内获得的某些资源,请使用finally
,如果不关闭,这些资源将长时间处于阻塞状态。考虑一下I / O流,数据库连接/事务和类似的东西。不要只是为了分配内存,这就是垃圾收集器的工作。
如果遵循这些规则,您会发现您的代码可以专注于其主要工作,不会杂乱无章地处理许多错误,并且在发生异常情况下仍然很健壮。
这完全取决于问题“ Class1.method()
的工作是什么?”。
可能是“打印这两个数字”。然后,当它得到NullPointerException
时,它将无法完成其工作,因此它不应正常返回,而应异常退出,最简单的方法是不执行任何操作(根本不尝试/不捕捉),而让异常框架自动完成工作。这将意味着其调用者获得原始的NullPointerException
:
public int method (int a, String b) {
System.out.println(a+" "+b.length());
}
如果Class1.method()
的工作是“打印这两个数字,但只有在有字符串的情况下”,那么您应该在内部捕获NullPointerException(或者最好用if
检查)并返回通常(“我已经完成了工作!”)。那么Class2.main()
应该对不打印为null的情况感到满意,并且在调用Class1.method()
之后没有理由进行任何错误处理。如果Class2.main()
不希望这种行为,那么在这种情况下就不应调用Class1.method()
。