[英]Throw exception instead of return in Java method
根据Coursera上的算法,第1部分 ,我正在Java上编写Deque
类。 目前,我基于数组的Deque
具有方法removeLast()
:
public Item removeLast() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
throw new NoSuchElementException("Stack underflow");
}
如果head == tail
表示Deque
为空,并且根据作业规范,我将在方法末尾而不是return
语句引发异常。 这段代码直接针对不变式( head != tail
)。
另一方面,方法可以这样重写:
public Item removeLastRewritten() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head == tail) {
throw new NoSuchElementException("Stack underflow");
}
Item tmp = array[--head];
array[head] = null;
return tmp;
}
我认为removeLast
是由以下原因更清楚地编写的:
always fail, only if ...
这是更可靠的方法,尤其是当方法代码将扩大并变得更加复杂时。 tail != head
和随后的if {}
代码块之间提供更清晰的链接。 我有以下问题:
removeLast
这样的书写被认为是适当/良好的做法吗? 没有错误的答案。 在GrepCode中,您可以找到建议的每种口味:
E java.util.PriorityQueue.next()
public E More ...next() {
if (... != ...)
throw new ConcurrentModificationException();
...
if (...) {
return lastRetElt;
}
throw new NoSuchElementException();
}
E org.fluentlenium.core.domain.FluentList.first()
public E More ...first() {
if (this.size() == 0) {
throw new NoSuchElementException("Element not found");
}
return this.get(0);
}
为什么它看起来怪异的原因是因为你忽略了else
你的块if
块,其中将纳入要么剩自带后if
在这两个你的方法块。 之所以可以在这里使用它,是因为抛出的异常会破坏方法的流程。
我认为最好不要依赖它,而要友好并直观地使用if-else
块。
public Item removeLastRewrittenAgain() {
if (size() == array.length / 4) {
resize(array.length / 2);
}
if (head != tail) { // invert the if-else block if preferred, it would not make any difference
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
}
我真的不喜欢在方法结束前抛出异常的另一个原因是,我坚信并因此彻底使用a single point of exit
的概念,这意味着我不会将方法留在中间的某个地方。我相信对于不熟悉该代码的人来说更难阅读。
返回值(或引发异常)的一个地方:方法的最底层。
如果您明确提及else
,则无论选择如何,您的代码都将更具可读性。
然后是两难
if (head != tail) {
Item tmp = array[--head];
array[head] = null;
return tmp;
} else {
throw new NoSuchElementException("Stack underflow");
}
与
if (head == tail) {
throw new NoSuchElementException("Stack underflow");
} else {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
在这里,我非常喜欢第二个。 当我阅读if语句的“复杂部分”时,我想知道为什么我实际上位于if
。 阅读第一个变体时,如果引发异常,则if的全部原因才变得显而易见。
我想你也可以通过写来解决
boolean isEmpty = head == tail;
if (!isEmpty) {
Item tmp = array[--head];
array[head] = null;
return tmp;
}
throw new NoSuchElementException("Stack underflow");
但是我更喜欢在您知道有问题时立即引发异常的版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.