在Java方法中抛出异常而不是返回

时间:2015-07-24 07:24:45

标签: java coding-style

根据Coursera上的Algorithms, Part 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更清楚地写出了这些原因:

  1. 坚持悲观场景 - always fail, only if ...这是更可靠的方法,特别是当方法代码会扩大并变得更加复杂时。
  2. 在不变tail != head和后续if {}代码块之间提供更清晰的链接。
  3. 我有以下问题:

    1. 哪种方法更好?
    2. removeLast
    3. 这样的写作被认为是合适/良好的做法
    4. 什么被认为是Java的最佳实践?是否有任何代码风格(我找不到)?

3 个答案:

答案 0 :(得分:2)

没有错误的答案。在GrepCode中,您可以找到您提出的每种口味:

  1. 使用!= 运算符并在方法结束时使用if:
  2. E java.util.PriorityQueue.next()

    public E More ...next() {
        if (... != ...)
            throw new ConcurrentModificationException();
        ...
        if (...) {
            return lastRetElt;
        }
        throw new NoSuchElementException();
    }
    
    1. 使用 == 运算符
    2. 在if中

      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);
      }
      

答案 1 :(得分:1)

它看起来很奇怪的原因是因为你省略了>块的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"); } } 的概念,这意味着我不会离开我觉得中间某处的方法对于不熟悉代码的人来说更难阅读。

返回您的价值的一个地方(或抛出的例外):您方法的最底层。

答案 2 :(得分:1)

如果您明确提及private static bool FilesPresent() { IEnumerable<string> dirs = Directory.EnumerateDirectories(dataFileDirectoryPath, "*.*", SearchOption.TopDirectoryOnly); return dirs.Any(d => Directory.EnumerateFiles(d, "*.*", SearchOption.AllDirectories).Any()); } ,则无论您的选择如何,您的代码都会变得更具可读性。

然后是

的困境
else

if (head != tail) {
    Item tmp = array[--head];
    array[head] = null;
    return tmp;
} else {
    throw new NoSuchElementException("Stack underflow");
}

在这里,我非常喜欢第二个。当我正在阅读if语句的“复杂部分”时,我想知道为什么我实际上在if (head == tail) { throw new NoSuchElementException("Stack underflow"); } else { Item tmp = array[--head]; array[head] = null; return tmp; } 内。在阅读第一个变体时,只有当你抛出异常时,if的全部原因才会变得明显。

我想你也可以通过写

来解决这个问题
if

但我更喜欢一旦你知道错误就抛出异常的版本。