尝试使用Java两次处理异常

时间:2019-01-15 18:30:42

标签: java

我正尝试两次处理异常

第一个是已定义方法的核心:

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块没有执行?

2 个答案:

答案 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)

您会找到许多有关引发和捕获异常机制的文章。我发现更重要的是如何充分利用异常概念。

这并不完全是您的问题的答案,但也许可以澄清当前情况背后的一些概念。

经验法则

  1. 如果某个方法完成了其工作,则应正常返回。如果这样做失败,则应引发异常而不是正常返回。从您的方法中产生的异常应该包含有关该问题的信息(大多数标准异常已经做得很好)。

  2. 在从属方法中,通常不应使用try / catch。如果出现问题(方法中出现一些异常),则您的方法通常无法完成其工作,它应该通过异常来告知调用方,最简单的方法就是让异常通过。 p>

  3. 在顶层方法(例如,主菜单,主菜单操作,单击按钮的操作)中,捕获所有异常,通知用户(可能是管理员),然后继续(如果可能/适当)。 / p>

  4. 如果您的方法遇到一个异常(例如NullPointerException),并希望向其调用方显示另一个异常,请捕获该异常,使用原始的cause创建所需的新异常,并抛出这个新异常。我个人希望尽量避免这种“例外翻译”。

  5. 如果必须关闭体内获得的某些资源,请使用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()