如何有效处理任何类型的异常?

时间:2010-12-10 08:12:54

标签: java exception exception-handling

异常处理是从崩溃中保存应用程序的最有用的机制。甚至我们大多数人都遵循异常处理机制。即使我看到许多仍然得到例外。我们是否应该以应有的方式处理异常?我的问题是,处理任何异常的最佳方法是什么?

我想澄清一些事情。当我说处理异常时,这不仅意味着捕获适当的异常消息并显示或记录它。相反,它假设处理异常的纠正措施。

让我们考虑一下这段代码:

try {
  someMethod1();
} catch (MyException e) {
  System.out.println(e.getMessage());
} catch (YourException e) {
  System.out.println(e.getMessage());
}

在上面的代码中,“MyException”和“YourException”可能无法捕获所有类型的Exception。但是,当然我们可以使用“java.lang.Exception”。我们如何识别正确的异常类型?以及如何处理该异常?特别是在使用外部库时。

根据要求提供更多细节。

由于

8 个答案:

答案 0 :(得分:7)

您不想捕获运行时异常。原因是,你只是在那里隐藏一个bug。而是让应用程序失败并修复它。要回答你的问题,如果你抓住了Throwable,你将基本上吃掉任何类型的例外。

经验法则:仅捕获应用程序异常。

答案 1 :(得分:4)

我不知道我是否真的得到了你问题的含义,但是,你可以在某个代码块中捕获尽可能多的语法:

try {
  someMethod1();
} catch (MyException e) {
  System.out.println(e.getMessage());
} catch (YourException e) {
  System.out.println(e.getMessage());
} catch (IOException e) {
   //handle
} catch (SQLException e) {
   //handle
}

并且,基于异常层次结构,当您捕获异常时,您还捕获此异常的每个子类型,因此,当您需要捕获每个意外错误条件时,可以为java.lang.Exception添加catch(在最后一个捕获声明中)

try {
  someMethod1();
} catch (MyException e) {
  System.out.println(e.getMessage());
} catch (YourException e) {
  System.out.println(e.getMessage());
} catch (Exception e) {
   //handle generic unexpected exception
}

您也可以捕获超级界面Throwable,但不建议这样做,因为唯一的区别是,除了例外,您也会捕获错误。错误是致命的条件,不应该处理,因为它们用来表示java VM的严重问题,如Out of Memory,Stack Overflow等。

这些链接对于如何处理java Exceptions非常有用:

问候。

答案 2 :(得分:1)

来自Software Engineering Radio播客的家伙在Error Handling上有两集非常好的剧集。

答案 3 :(得分:1)

如果您真的想要捕获所有可能的异常,那么抓住Throwable就是您想要做的:

try {
    somethingThatMayFail();
} catch (Throwable t) {
    t.printStackTrace();
}

但是,这往往是一个坏主意。 如果你不知道它们为什么会发生,或者如何在它们之后进行清理,你不应该抓住任何例外。不崩溃不一定是件好事 - 如果你的程序坏了,崩溃就是负责任的事情要做。考虑这种方法:

public Thing loadThing(long id){
    try {
        return doLoad(id);
    } catch (Throwable t) {
        // What do we do here?
    }
}

编译器强制您从方法的每个可能的执行路径返回或抛出某些东西,但只有非异常路径才允许我们返回合理的东西。我们可以从catch子句返回null,但是调用代码可能会忘记检查null的返回值,这意味着你最终会得到一个NullPointerException,因为它更难以解密不告诉你真正的错误是什么或它发生的地方。

例外是好的。每种明智的语言都有它们的原因。

答案 4 :(得分:1)

可以通过反射检查任何对象的类型。但我不喜欢使用它。

try {
    throw new Exception1();
} catch (Throwable t) {
    // just get name
    System.out.println(t.getClass().getName() + " caught");

    // or try instanceof - this is not nice approach IMO
    if (t instanceof Exception1) {
        System.out.println("yes exception1");
    }
}
BTW确实想过或听说过AOP?更准确地说是AspectJ。面向方面的编程可以回答您的问题如何在代码仍然干净且易于维护的情况下打印或记录异常。如果您使用的是Java EE和EJB,则可以尝试使用拦截器机制而不是AspectJ。我建议你阅读一些关于AOP和AspectJ(用于Java)的内容。

欢呼声

答案 5 :(得分:0)

听起来你正在试图弄清楚如何知道你何时处理了所有可能的异常。如果你只是不在你的方法上加上throws子句,那么编译器会告诉你需要把处理程序放到哪个例外。

答案 6 :(得分:0)

如果您正在使用Eclipse,一种方法是编写没有异常处理的代码,它将使您看到代码可能抛出的异常类型。 如果您希望程序序列在编码时继续,那么您只能包围可能引发异常的代码部分,并在Catch块中执行必要的步骤,以便您的程序在您想要的流程中工作。

类似

” 代码......

尝试{ 东西.... } catch(someException e){ // 处理它 }

尝试{ 东西.... } catch(someException e){ // 处理它 }

代码...... “

但是,此代码不会捕获可能发生的任何异常(即,不是因为您的代码)。为此,外部尝试捕获可能会帮助您发现它是其他东西

喜欢

” 尝试 { 代码......

尝试{ 东西.... } catch(someException e){ // 处理它 }

尝试{ 东西.... } catch(someException e){ // 处理它 }

代码...... } catch(运行时e){ //告诉user / log发生意外的事情 } “

答案 7 :(得分:-1)

您的代码是正确的。如果someMethod1()方法没有声明任何其他异常,则它们是RuntimeExceptions,您应该捕获RuntimeException