哪个层应该被捕获?

时间:2014-05-30 06:23:46

标签: java exception

我已经实现了一个Queue,然后是一个名为ImplementStackUsingQueue的包装器。 注意 - 我的问题与实现的准确性或逻辑无关。它只涉及异常处理。

队列实现类似于

 public synchronized boolean add(int x) {
        if (currentSize == maxSize) {
            throw new IllegalStateException("The queue is full: front size: " + rear);
        }

        queue[rear++] = x; // USE.
        rear = (rear + 1) % maxSize;     // NEXT.
        currentSize++;

        return true;
    }

使用此队列实现堆栈的包装器如下所示:

  public void push(T x) {
        queue2.add(x);
        queue2.addAll(queue1);
        queue1 = queue2;
        queue2 = new LinkedList<T>();
    }

现在,我的包装器,截至目前,依赖于底层Queue来抛出IllegalStateException。 我的问题是 - 依靠底层组件抛出异常是好的做法还是值得在currentSize = maxSize中复制异常处理条件ImplementStackUsingQueue并在控制进入底层之前处理异常?

1 个答案:

答案 0 :(得分:2)

这个主题是基于意见的,但多年来已经达成了一些共识。其中一个是"Don't use exceptions for flow control"

对于发布的代码,如果无法将元素添加到队列中,则返回false会更有意义。

现在,对于您的问题“依靠底层组件抛出异常是一种好习惯吗?” 如果抛出异常来控制流量。

“是否值得在ImplementStackUsingQueue中复制异常处理条件currentSize = maxSize并在控制进入底层之前处理异常?” 不,基础级别应该只指示是否可以将该元素添加到队列中:

public synchronized boolean add(int x) {
    if (currentSize == maxSize) {
        return false; // indicate in the javadocs when the false is returned
    }

    queue[rear++] = x; // USE.
    rear = (rear + 1) % maxSize;     // NEXT.
    currentSize++;

    return true;
}

很难知道“push”正在做什么,因为queue1和queue2可以被修改或在其他地方使用。如果可以隔离对队列的更改,那么如果无法将该元素添加到队列,则“push”应该可以返回false。如果队列不接受null元素,那么如果无法将元素推送到队列,则可以返回null,否则返回推送的元素。但请注意,“推”抛出异常会非常好。例如,如果queue2为null,它可能会抛出NPE。

同样,这是基于意见的,所以我的意见很多。