我已经实现了一个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
并在控制进入底层之前处理异常?
答案 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。
同样,这是基于意见的,所以我的意见很多。