簡體   English   中英

拋出異常而不是在Java方法中返回

[英]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是由以下原因更清楚地編寫的:

  1. 堅持悲觀的情況- always fail, only if ...這是更可靠的方法,尤其是當方法代碼將擴大並變得更加復雜時。
  2. 在不變tail != head和隨后的if {}代碼塊之間提供更清晰的鏈接。

我有以下問題:

  1. 哪種方法更好?
  2. removeLast這樣的書寫被認為是適當/良好的做法嗎?
  3. Java的最佳實踐是什么? 是否有任何代碼風格(我找不到)?

沒有錯誤的答案。 在GrepCode中,您可以找到建議的每種口味:

  1. 在帶有!=運算符的if中,並在方法結尾:

E java.util.PriorityQueue.next()

public E More ...next() {
    if (... != ...)
        throw new ConcurrentModificationException();
    ...
    if (...) {
        return lastRetElt;
    }
    throw new NoSuchElementException();
}
  1. 在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);
}

為什么它看起來怪異的原因是因為你忽略了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM