Java Exceptions

1. 常见错误分类

一般的,errors可以分为以下几类:

  • user input errors
  • device errors or physical limitations
  • code errors

2. 常用错误处理方式

2.1 error code

一种常用的错误处理方法是返回error code,由calling method根据error code做不同处理。

但是有些情形下error code并不方便使用,比如如何取分错误码和与错误码相同的有效值。

2.2 exception handling

The mission of exception handling is to transfer control from where the error occured to an error handler that can deal with the situation.

当出现错误时,程序应当恢复到某个安全状态并重新来过,或者保存当前工作安全退出,但是这并不容易,关键就是程序控制权如何从触发错误的地方跳转到处理错误的地方。

Java allows every method an alternative exit path if it is unable to complete its task in the normal way:

  • 首先,throws an object that encapsulates the error information
  • 然后,the exception-handling mechanism begins its search for an exception handler that can deal with this particular error condition
  • 注意,这条alternative exit path与正常的程序逻辑无关,the method exits immediately, and it does not return its normal value, and the execution does not resume at the code that called the method

3. Java exception hierarchy

3.1 Throwable

Throwable是整个Java exception hierarchy的基类,其下分为:

  • Error
  • Exception

3.2 Error

the error hierarchy describes internal errors and resource exhaustion situations inside the Java runtime system.

You should not throw an object of this type. There is little you can do if sucn an internal error occurs, beyond notifying the user and trying to terminate the program gracefully.

3.3 Exception

Exception可以分为两类:

  • RuntimeException
  • 其他

RuntimeException意味着编码错误,比如
a bad cast, an out-of-bounds array access, a null pointer access等。

其他Exception一般是出现了某种意外,some bad things happened, 比如,打开一个不存在的文件。

为什么打开不存在的文件不是RuntimeException?因为这不是你的代码能控制的,你先校验文件是否存在也没用,可能你校验时是存在的,但你打开时就不存在了。

4. Checked exception vs unchecked exception

Error和RuntimeException这两支,我们称为unchecked exception.

除Error和RuntimeException这两支外的其他Exception,我们称为checked exception.

The compiler checks that you provide exception handlers for all checked exceptions:

  • 对于Error,你无能为力,所以是unchecked exception
  • 对于RuntimeException,编码错误是你的责任,你应当避免它们出现,所以也是unchecked exception
  • 对于其他exceptions,你必须做好处理它们的准备,所以是checked exception

5. Checked exception declaration

对于你的方法可能抛出的checked exceptions,你必须在method declaration中通过throws声明出来。

如果可能抛出多个checked exceptions,那么需要都列出来,使用逗号分隔。

public Image loadImage(String name) throws FileNotFoundException, EOFException {...}

注意,unchecked exception不应当出现在你的throws声明中:

  • 对于Error,你无能为力
  • 对于RuntimeException,你应当避免它们出现,而不是声明可能抛出它们。

6. Throw an exception

如何抛出exception呢?很简单:

  • find an appropriate exception class
  • make an object of that class
  • throw it

没有合适的standard exception class可用?没有关系,你可以自定义一个

class FileFormatException extends IOException {
    public FileFormatException() {}
    public FileFormatException(String gripe) {
        super(gripe);
    }
}

一般的,我们为自定义的exception class提供两个constructors:a default constructor and a constructor with a detailed message.

7. Catch exceptions

try {
    xxx
} catch (ExceptionType1 | ExceptionType 2 e) {
    xxx
} catch (ExceptionType3 e) {
    xxx
}

对于checked exceptions,如果你知道如何处理它们,那么你可以catch它们,这样就不用抛出它们了。

As a general rule, you should catch those exceptions that you know how to handle and propagate those that you do not know how to handle.

8. Rethrow exceptions

try {
    xxx
} catch (SQLException e) {
    throw new ServletException("xxx error").initCause(e);
}

这是rethrow exception的常用方式。通过这种方式,我们可以包装出一个更抽象的exception,或者把一个checked exception转换成一个RuntimeException.

9. finally

try {
    try {
        xxx
    } finally {
        xxx
    }
} catch (Exception e) {
    xxx
}

the inner try block has a single responsibility: to make sure that the resources are released

the outer try block has a single responsibility: to ensure that errors are reported.

注意,the body of the finally clause is intended for cleaning up resources. Don't put statements that change the control flow (return, throw, break, continue) inside a finally clause.

10. try-with-Resources

try (Resource res = xxx) {
    xxx
}

从Java 7开始,try-finally结构可以简化为try-with-Resources.

要求Resource必须是AutoCloseable的实现类,when the try block exits, then res.close() is called automatically.

A difficulty arises when the try block throws an exception and the close method also throws an exception. The original exception is rethrown, and any exceptions thrown by close methods are considered "suppressed". They are automatically caught and added to the original exception with the addSuppressed method.

你可能感兴趣的:(Java Exceptions)