簡體   English   中英

在我的特定情況下,我是否應該使用自定義異常?

[英]In my particular situation should I use custom exceptions or not?

如果不滿足某些條件,我必須創建這個學生存儲庫,其中需要拋出異常。 我的問題是:我應該創建自己的自定義異常,還是應該使用預定義的異常? 我將在下面留下我的一部分代碼

public class StudentRepository {

private static List<Student> studentList = new ArrayList<>();
private static Set<Student> studentsByAge = new TreeSet<>(new AgeComparator());
private static Set<Student> studentsByLastName = new TreeSet<>(new LastNameComparator());

public static Student addStudent(String firstName, String lastName, String gender, LocalDate dateOfBirth) {


    if (firstName.trim().isEmpty() || lastName.trim().isEmpty()) {
        throw new NullPointerException("Last name or first name field may be empty");
    } else if (!(gender.equalsIgnoreCase("m") || gender.equalsIgnoreCase("f"))) {
        throw new IllegalArgumentException("Gender should be 'M or 'F");
    } else if (dateOfBirth.isBefore(LocalDate.of(1900, 1, 1)) ||
            dateOfBirth.isAfter(LocalDate.now())) {
        throw new IllegalArgumentException("Date of birth should be between 1900 and current year");
    }

    Student newStudent = new Student(firstName, lastName, dateOfBirth, gender);
    studentList.add(newStudent);
    return newStudent;
}

public static void deleteStudentByCnp(String cnp) {
    Student studentToDelete = null;

    for (Student student : studentList) {
        if (student.getCnp().equals(cnp)) {
            studentToDelete = student;
            studentList.remove(studentToDelete);
            break;
        } else {
            throw new NullPointerException("The student does not exist");
        }
    }
}

您可以查看 Oracle 關於已檢查與未檢查異常主題的建議,這應該更清楚: https : //docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

該頁面的摘要如下

這是底線准則:如果可以合理地期望客戶端從異常中恢復,請將其設為已檢查異常。 如果客戶端無法從異常中恢復,請將其設為未經檢查的異常。

您還可以在此處閱讀有關自定義異常與標准異常用法的更多信息: https : //stackify.com/java-custom-exceptions/

通常這取決於客戶端的行為 - 客戶端可以用這個異常做什么。 如果它只是記錄錯誤而僅此而已 - 那么 IllegalArgumentException 應該就足夠了,但是如果您隨后將此錯誤返回給客戶端,例如使用 REST - 那么創建具有適當結構的自定義異常將是有意義的,該異常將被序列化並返回以響應保持響應錯誤的一致結構。

無論如何,請不要使用NullPointerException除了某些意外為 null 的情況(即程序員的錯誤)。 在您的情況下,我會用自定義異常替換 NullPointerExceptions。

假設這些規則(性別必須是MF等)被視為先決條件(因為文檔指出:您傳遞的參數必須遵守這些規則),拋出的正確異常是IllegalArgumentException 除了 param 不能為 null 的先決條件,在這種情況下NullPointerException是合適的。 談論可恢復性不適用於這種異常——方法的作者不知道調用者是否是那種可以“合理地從異常中恢復”的代碼。 他們很有可能不能(比如,它是通過網絡提供的文本,並且沒有機制向調用者發回信號:呃,你沒有遵循那里商定的規范,或者它來自配置文件),所以在這里未經檢查可能更好。 IllegalArgumentException恰到好處。

但是, NullPointerException在這里顯然是非常糟糕的用法 那就是表示一個事情是空的,這不是預期的,就是這樣,所以不要像這樣濫用它!

請注意,您的代碼有很多問題:

  • 2 性別? 現在是 2021 年。這可能永遠不會被接受,但現在肯定不是。 為什么你需要知道學生的性別? 將正確的敬語放在字母上? 擺脫性別並為“榮譽”添加一個字段。 許多國家都有指導方針,禁止在不相關時詢問性別。 我在這里似乎無關緊要。 (榮譽可能是;如果您需要,請要求)。
  • 如果您想忽略它並強制使用 2 個性別,請強制使用它,然后編寫一個枚舉。 您想避免某些輸入可以聲明但無效的整個想法 - 因為那樣您需要繼續編寫代碼以對無效狀態做出反應。 如果一個對象或參數根本不可能是錯誤的,那就更好了。 枚舉不可能是錯誤的,或者至少,只有在例如它為空時才會是錯誤的,這是一種更簡單的檢查。
  • 您的“日期”錯誤顯示為“當前年份”,但實際上是在檢查當前日期。
  • 性別錯誤有錯別字。
  • 您的姓氏/名字消息不清楚,並且不遵循 Java 樣式。 你應該陳述規則,而不是問題。 '名字和姓氏不得為空'。 沒有什么“可能”的。
  • 您的delete方法將檢查列表中的第一個學生。 如果它的 CNP 匹配,則將其刪除,然后就完成了。 如果不匹配,您的代碼會立即出錯。 除了列表中的第一個之外,它從不掃描任何學生。 該異常拋出需要在for循環之外。
  • Map在這里聽起來像是更好的數據結構; 目前,隨着學生越來越多,您的刪除代碼將花費越來越長的時間。
  • 當您使代碼更通用時,“名字”和“姓氏”的概念也很可疑。 這是個好消息:它簡化了我們作為開發人員的生活。 只需有一個“全名”字段。 現在,您不再需要計算如何將名字和姓氏組合在一起。 您只需打印“全名”字段的值。 如果您需要更短的名稱,請將其添加為字段。 性別也一樣:不要根據性別找出正確的敬語,只需將“敬語”字段的值放在那里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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