2008-11-18 75 views
64

我想知道爲什麼assert關鍵字在Java中如此不足?我幾乎從未見過他們用過,但我認爲他們是一個好主意。當然,我更喜歡的簡潔:未被使用的Java斷言

assert param != null : "Param cannot be null"; 

到的詳細程度:

if (param == null) { 
    throw new IllegalArgumentException("Param cannot be null"); 
} 

我懷疑是他們未充分利用的,因爲

  • 他們到達比較晚(Java 1.4中) ,那時很多人已經建立了他們的Java編程風格/習慣
  • 它們在運行時默認關閉,爲什麼OH爲什麼?
+0

它是Java 1.4中介紹了斷言。 – 2008-11-18 19:12:08

+12

注意:你可以寫assert param!= null:「Message」;即。放下括號。與返回一樣多(someValue);這是一種語言功能,不是函數調用。 – PhiLho 2008-12-15 09:16:15

+0

@丹恩謝謝,我已經更新了問題 – 2009-11-09 14:40:13

回答

62

斷言是,在理論上,測試invariants,假設必須爲了是真實的代碼正確完成。

示出了用於有效的輸入,這對於一個斷言一個典型的使用正在測試,因爲它是例如,通常,用戶提供。

斷言並不一般在生產代碼中使用,因爲有一個開銷,假設在不變的情況下失敗被抓的開發和測試過程中編碼錯誤。

你對他們「遲到」Java的觀點也是他們沒有被廣泛看到的原因。

此外,單元測試框架允許一些需要編程斷言爲外部代碼被測試。

0

事實上,他們在Java中到達1.4

我認爲主要的問題是,當你的代碼的環境下你不喜歡自己的Eclipse或J2EE服務器直接管理JVM選項(在這兩種情況下,它可以改變jvm選項,但是你需要深入搜索才能找到它可以完成的地方),使用if和exception(或者更糟糕的是不使用任何東西)會更容易(我的意思是它需要更少的努力)。

1

斷言是非常有限的:你只能測試布爾條件,你需要編寫每次有用的錯誤消息的代碼。將它與JUnit的assertEquals()進行比較,它允許從輸入生成一個有用的錯誤消息,甚至在JUnit runner中的IDE中並排顯示兩個輸入。

而且,你不能搜索斷言在迄今爲止我見過的任何IDE但每一個IDE可以搜索方法調用。

19

Programming with Assertions

默認情況下,斷言是在運行時禁用。兩個命令行開關允許您選擇性地啓用或禁用斷言。

這意味着如果您不能完全控制運行時環境,則不能保證斷言代碼甚至會被調用。斷言意味着在測試環境中使用,而不是用於生產代碼。您不能用斷言替換異常處理,因爲如果用戶運行斷言已禁用的應用程序(默認爲),則您的所有錯誤處理代碼都將消失。

56

這是濫用斷言來使用它們來測試用戶輸入。在無效輸入上拋出IllegalArgumentException更正確,因爲它允許調用方法捕獲異常,顯示錯誤並執行所需的任何操作(再次請求輸入,退出,無論如何)。

如果該方法是裏面的類中的一個私有方法,斷言是好的,因爲你只是想確保你不小心傳遞一個空參數。您可以使用斷言進行測試,並且當您測試了所有路徑並且未觸發斷言時,可以關閉它們,以免浪費資源。作爲評論,它們也很有用。一個方法開始時的assert對於維護者來說應該是遵循某些先決條件的良好文檔,並且末尾有一個assert,後續條款記錄了該方法應該做什麼。它們可以與評論一樣有用;另外,因爲有了斷言,他們實際上是在測試他們記錄的內容。

斷言是用於測試/調試,沒有錯誤檢查,這就是爲什麼他們是默認關閉的:從使用斷言驗證用戶輸入的勸阻人。

18

在「有效的Java」,約書亞布洛赫建議(在「檢查有效參數」主題)是(有點像一個簡單的規則採用),用於公共方法,我們將驗證的參數,如果拋出必要的異常發現無效,對於非公開的方法(它們沒有公開,你作爲它們的用戶應該確保它們的有效性),我們可以使用斷言。

YC

2

我不知道爲什麼你會懶得寫斷言,然後用標準的替換他們,如果再條件語句,爲什麼不寫條件如同第一個地方?

斷言僅用於測試,他們有兩個副作用:(!這就是爲什麼你可以將其關閉)啓用時較大的二進制文件,並導致性能下降

斷言不應該用於驗證的條件,因爲這意味着您的應用程序在運行時的行爲不同時,斷言被啓用/禁用 - 這是一場噩夢!

1

斷言是有用的,因爲它們:

  • 捕捉編程錯誤早期使用代碼

認爲他們

  • 文件代碼代碼自我驗證。如果它們失敗了,它應該意味着你的程序被破壞並且必須停止。在單元測試時始終打開它們!

    The Pragmatic Programmer他們甚至建議讓他們在生產中運行。

    離開斷言已打開

    用斷言防止不可能。

    請注意,斷言拋出AssertionError,如果他們失敗,所以不抓捕獲異常。

  • 0

    正如其他人所說:斷言不適合驗證用戶輸入。

    如果您關心的是詳細程度,我建議您查看我寫的圖書館:https://bitbucket.org/cowwoc/requirements/。這將允許您使用很少的代碼來表示這些檢查,它甚至會產生對你代表的錯誤消息:

    requireThat("name", value).isNotNull(); 
    

    ,如果你堅持要用斷言,你也可以這樣做:

    assertThat("name", value).isNotNull(); 
    

    輸出將是這樣的:

    java.lang.NullPointerException: name may not be null