Java 菜鳥教程

Java 流程控制

Java 數(shù)組

Java 面向?qū)ο?I)

Java 面向?qū)ο?II)

Java 面向?qū)ο?III)

Java 異常處理

Java 列表(List)

Java Queue(隊(duì)列)

Java Map集合

Java Set集合

Java 輸入輸出(I/O)

Java Reader/Writer

Java 其他主題

Java 斷言(Assert)

在本教程中,我們將借助示例學(xué)習(xí)Java assert語句(Java斷言)。

Java中的斷言通過測試我們認(rèn)為是正確的代碼來幫助檢測錯誤。

使用assert關(guān)鍵字進(jìn)行斷言。

其語法為:

assert condition;

這里condition是一個布爾表達(dá)式,我們假定在程序執(zhí)行時為真。

啟用斷言

默認(rèn)情況下,斷言在運(yùn)行時被禁用并被忽略。

為了啟用斷言,我們使用:

java -ea:arguments

或者

java -enableassertions:arguments

啟用斷言且條件為時true,程序?qū)⒄?zhí)行。

但是,如果在啟用斷言時條件計(jì)算為false, JVM會拋出AssertionError,程序會立即停止。

示例1:Java 斷言

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length == 2;
    System.out.println("這個星期有 " + weekends.length + " 個周末");
  }
}

輸出結(jié)果

這個星期有 3 個周末

我們得到上面的輸出,因?yàn)樵摮绦驔]有編譯錯誤,并且默認(rèn)情況下,斷言被禁用。

啟用斷言后,我們得到以下輸出:

Exception in thread "main" java.lang.AssertionError

斷言的另一種形式聲明

assert condition : expression;

在這種形式的斷言語句中,將表達(dá)式傳遞到AssertionError對象的構(gòu)造函數(shù)。 如果條件為false,則該表達(dá)式的值顯示為錯誤的詳細(xì)信息。

詳細(xì)消息用于捕獲和傳輸斷言失敗的信息,以幫助調(diào)試問題。

示例2:帶有表達(dá)式Java斷言示例

class Main {
  public static void main(String args[]) {
    String[] weekends = {"Friday", "Saturday", "Sunday"};
    assert weekends.length==2 : "There are only 2 weekends in a week";
    System.out.println("There are " + weekends.length + "  weekends in a week");
  }
}

輸出結(jié)果

Exception in thread "main" java.lang.AssertionError: There are only 2 weekends in a week

從上面的示例可以看出,表達(dá)式被傳遞給AssertionError對象的構(gòu)造函數(shù)。如果我們的假設(shè)是正確的false,并且啟用了斷言,則會拋出異常并顯示一條適當(dāng)?shù)南ⅰ?/p>

此消息有助于診斷和修復(fù)導(dǎo)致斷言失敗的錯誤。

為特定的類和包啟用斷言

如果我們不向斷言命令行開關(guān)提供任何參數(shù),

java -ea

這將在除系統(tǒng)類之外的所有類中啟用斷言。

我們還可以使用參數(shù)為特定的類和包啟用斷言。 可以提供給這些命令行開關(guān)的參數(shù)為:

在類名中啟用斷言

為了對程序Main的所有類啟用斷言,

java -ea Main

只啟用一個類,

java -ea:AnimalClass Main

這只允許在Main程序的AnimalClass中使用斷言。

在包名稱中啟用斷言

要對包c(diǎn)om.animal及其子包啟用斷言

java -ea:com.animal... Main

在未命名的包中啟用斷言

在當(dāng)前工作目錄中的未命名包中啟用斷言(當(dāng)我們不使用package語句時)。

java -ea:... Main

在系統(tǒng)類中啟用斷言

為了在系統(tǒng)類中啟用斷言,我們使用不同的命令行開關(guān):

java -esa:arguments

java -enablesystemassertions:arguments

可以提供給這些開關(guān)的參數(shù)是相同的。

禁用斷言

要禁用斷言,我們使用:

java -da arguments

java -disableassertions arguments

要在系統(tǒng)類中禁用斷言,我們使用:

java -dsa:arguments

java -disablesystemassertions:arguments

禁用斷言時可以傳遞的參數(shù)與啟用斷言時相同。

斷言的優(yōu)點(diǎn)

  1. 快速高效地檢測和糾正錯誤。

  2. 斷言檢查僅在開發(fā)和測試期間進(jìn)行。它們會在運(yùn)行時自動在生產(chǎn)代碼中刪除,因此不會減慢程序的執(zhí)行速度。

  3. 它有助于刪除樣板代碼并使代碼更具可讀性。

  4. 重構(gòu)和優(yōu)化代碼,以增強(qiáng)其正確運(yùn)行的信心。

何時使用斷言

1.無法訪問的代碼

無法訪問的代碼是我們嘗試運(yùn)行該程序時不會執(zhí)行的代碼。使用斷言來確保無法訪問的代碼實(shí)際上是無法訪問的。

讓我們舉個實(shí)例。

void unreachableCodeMethod() {
  System.out.println("Reachable code");
  return;
  // Unreachable code
  System.out.println("Unreachable code");
  assert false;
}

讓我們再來看一個沒有默認(rèn)情況的switch語句示例。

switch (dayOfWeek) {
  case "Sunday":
    System.out.println("It’s Sunday!");
    break;
  case "Monday":
    System.out.println("It’s Monday!");
    break;
  case "Tuesday":
    System.out.println("It’s Tuesday!");
    break;
  case "Wednesday":
    System.out.println("It’s Wednesday!");
    break;
  case "Thursday":
    System.out.println("It’s Thursday!");
    break;
  case "Friday":
    System.out.println("It’s Friday!");
    break;
  case "Saturday":
    System.out.println("It’s Saturday!");
    break;
}

上面的switch語句表明,一周中的天數(shù)只能是以上7個值中的一個。沒有默認(rèn)情況意味著程序員相信這些情況中的一個將始終被執(zhí)行。

但是,在某些假設(shè)實(shí)際上是錯誤的情況下,可能尚未考慮某些情況。

應(yīng)該使用斷言來檢查此假設(shè),以確保未達(dá)到默認(rèn)switch條件。

default:
    assert false: dayofWeek + " is invalid day";

如果dayOfWeek其值不是有效日期,則拋出AssertionError。

2.記錄假設(shè)

為了記錄其基本假設(shè),許多程序員使用注釋。讓我們舉個實(shí)例。

if (i % 2 == 0) {
    ...
} else { // We know (i % 2 == 1)
    ...
}

請改用斷言。

隨著程序的增長,注釋可能會過時和不同步。 但是,我們將不得不更新assert語句; 否則,它們也可能因有效條件而失敗。

if (i % 2 == 0) {
   ...
} else {
    assert i % 2 == 1 : i;
    ...
}

什么時候不使用斷言

1.公共方法中的參數(shù)檢查

用戶可以提供公共方法中的參數(shù)。

因此,如果使用斷言來檢查這些參數(shù),則條件可能會失敗并導(dǎo)致AssertionError。

與其使用斷言,不如讓它產(chǎn)生適當(dāng)?shù)倪\(yùn)行時異常并處理這些異常。

2.對影響程序操作的表達(dá)式求值

不要調(diào)用方法或評估可能在斷言條件下影響程序操作的異常。

讓我們以一個列表示例為例,weekdays列表包含一周中所有天的名稱。

ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

assert weekdays.removeAll(weekends);

在這里,我們試圖從ArrayList weekdays中刪除元素Saturday和Sunday。

如果啟用了斷言,則程序可以正常運(yùn)行。但是,如果禁用了斷言,則不會刪除列表中的元素。這可能會導(dǎo)致程序失敗。

而是將結(jié)果分配給變量,然后使用該變量進(jìn)行斷言。

ArrayList<String> weekdays = new ArrayList<>(Arrays.asList("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ));

ArrayList<String> weekends= new ArrayList<>(Arrays.asList("Sunday", "Saturday" ));

boolean weekendsRemoved = weekdays.removeAll(weekends);
assert weekendsRemoved;

這樣,我們可以確保從weekdays中刪除所有weekends,而不考慮啟用或禁用斷言。 結(jié)果,它不會影響將來的程序操作。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清