zoukankan      html  css  js  c++  java
  • Effective Java 61 Throw exceptions appropriate to the abstraction

    Exception translation: higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction.

    // Exception Translation

    try {

    // Use lower-level abstraction to do our bidding

    ...

    } catch(LowerLevelException e) {

    throw new HigherLevelException(...);

    }

    Example

    /**

    * Returns the element at the specified position in this list.

    * @throws IndexOutOfBoundsException if the index is out of range

    * ({@code index < 0 || index >= size()}).

    */

    public E get(int index) {

    ListIterator<E> i = listIterator(index);

    try {

    return i.next();

    } catch(NoSuchElementException e) {

    throw new IndexOutOfBoundsException("Index: " + index);

    }

    }

    ExceptionChain: The lower-level exception (the cause) is passed to the higher-level exception, which provides an accessor method (Throwable.getCause ) to retrieve the lower-level exception:

    // Exception Chaining

    try {

    ... // Use lower-level abstraction to do our bidding

    } catch (LowerLevelException cause) {

    throw new HigherLevelException( cause);

    }

    // Exception with chaining-aware constructor

    class HigherLevelException extends Exception {

    HigherLevelException(Throwable cause) {

    super(cause);

    }

    }

    Note

    Most standard exceptions have chaining-aware constructors. For exceptions that don't, you can set the cause using Throwable's initCause method. Not only does exception chaining let you access the cause programmatically (with getCause ), but it integrates the cause's stack trace into that of the higher-level exception.

    Principle

    While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused.

    Solutions:

    1. The best way to deal with exceptions from lower layers is to avoid them by checking the validity of the higher-level method's parameters before passing them on to lower layers.
    2. The next best thing is to have the higher layer silently work around these exceptions, insulating the caller of the higher-level method from lower-level problems.(Log the exception using some appropriate logging facility such as java.util.logging which allows an administrator to investigate the problem, while insulating the client code and the end user from it.

    Summary

    If it isn't feasible to prevent or to handle exceptions from lower layers, use exception translation, unless the lower-level method happens to guarantee that all of its exceptions are appropriate to the higher level. Chaining provides the best of both worlds: it allows you to throw an appropriate higher-level exception, while capturing the underlying cause for failure analysis (Item 63).

  • 相关阅读:
    [ERROR] Terminal initialization failed; falling back to unsupported
    设计模式原则
    设计模式:概述
    INFO Dispatcher:42
    Exception occurred during processing request: id to load is required for loading
    Java编程基础篇第六章
    Spring (一)(未完~~~
    Spring MVC处理过程理解(一)
    Spring MVC源码解析(二)
    MyBatis拦截器(一)
  • 原文地址:https://www.cnblogs.com/haokaibo/p/throw-exceptions-appropriate-to-the-abstraction.html
Copyright © 2011-2022 走看看