English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Java フローコントロール

Java 配列

Java 面向オブジェクト(I)

Java 面向オブジェクト(II)

Java 面向オブジェクト(III)

Java 例外処理

Java リスト(リスト)

Java キュー(キュー)

Java Mapコレクション

Java Setコレクション

Java 入出力(I/O)

Java Reader/Writer

Java その他のトピック

Java アサート(Assert)

このチュートリアルでは、サンプルを用いてJavaのアサーション文(Java断言)を学びます。

Javaでは、アサーションは誤りを検出するために、正しいと考えているコードをテストする助けとなります。

assertキーワードを使用してアサーションを行います。

その文法は以下の通りです:

assert condition;

ここでのconditionは布尔値の式であり、プログラムの実行時に真であると仮定します。

アサーションを有効にする

デフォルトでは、アサーションは実行時に無効になり、無視されます。

アサーションを有効にするために、以下を使用します:

java -ea:arguments

または

java -enableassertions:arguments

アサーションを有効にして条件がtrueの場合、プログラムは通常通り実行されます。

しかし、アサーションを有効にするときに条件計算が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 + " 個周末");
  }
}

出力結果

この週には 3 個周末

この出力は、プログラムにコンパイルエラーがなく、デフォルトで断言が無効になっているため得られます。

断言を有効にした後、以下のような出力が得られます:

Exception in thread "main" java.lang.AssertionError

断言の別の形式声明

assert condition : expression;

この形式の断言文では、表現がAssertionErrorオブジェクトのコンストラクタに渡されます。条件がfalseの場合、その表現の値がエラーデータとして表示されます。

詳細なメッセージは、断言失敗の情報をキャプチャして伝達し、問題のデバッグを助けます。

示例2:带有表达式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");
  }
}

出力結果

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

上の例から、表現がAssertionErrorオブジェクトのコンストラクタに渡されていることがわかります。もし仮定が正しくfalseで、断言が有効になっている場合、例外が投げられ適切なメッセージが表示されます。

このメッセージは、断言失敗を引き起こすエラーの診断と修正に役立ちます。

为特定的类和パッケージに断言を有効にします

如果我们不向断言命令行开关提供任何参数

java -ea

这将在除系统类之外的所有类中启用断言。

我们还可以使用参数为特定的类和包启用断言。 可以提供给这些命令行开关的参数为:

在类名中启用断言

为了对程序Main的所有类启用断言

java -ea Main

只启用一个类

java -ea:AnimalClass Main

这只允许在Main程序的AnimalClass中使用断言。

在包名称中启用断言

要对包com.animal及其子包启用断言

java -ea:com.animal... Main

在未命名的包中启用断言

在当前工作目录中的未命名包中启用断言(当我们不使用package语句时)。

java -ea:... Main

在系统类中启用断言

为了在系统类中启用断言,我们使用不同的命令行开关:

java -esa:arguments

java -enablesystemassertions:arguments

可以提供给这些开关的参数是相同的。

禁用断言

要禁用断言,我们使用:

java -da arguments

java -disableassertions arguments

要在系统类中禁用断言,我们使用:

java -dsa:arguments

java -disablesystemassertions:arguments

禁用断言时可以传递的参数与启用断言时相同。

断言的优点

  1. 快速高效地检测和纠正错误。

  2. 断言检查仅在开发和测试期间进行。它们会在运行时自动在生产代码中删除,因此不会减慢程序的执行速度。

  3. 它有助于删除样板代码并使代码更具可读性。

  4. 重构和优化代码,以增强其正确运行的信心。

何时使用断言

1.无法访问的代码

无法访问的代码是我们尝试运行该程序时不会执行的代码。使用断言来确保无法访问的代码实际上是无法访问的。

让我们举个实例。

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

让我们再来看一个没有默认情况的switch语句示例。

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

break;7上面的switch文は、週の日数が上記の

个值中的一个。没有默认情况意味着程序员相信这些情况中的一个将始终被执行。

但是,在某些假设实际上是错误的情况下,可能尚未考虑某些情况。

应该使用断言来检查此假设,以确保未达到默认switch条件。
    default: + assert false: dayofWeek

" is invalid day"

2如果dayOfWeek其值不是有效日期,则抛出AssertionError。

.仮定の記録

随着程序的增长,注释可能会过时和不同步。 但是,我们将不得不更新assert语句; 否则,它们也可能因有效条件而失败。 2 if (i %
    ...
} // 多くのプログラマーは基本的な仮定を記録するためにコメントを使用します。以下に例を示します。 2 == 1We know (i %
    ...
}

)

請改用断言。

随着程序的增长,注释可能会过时和不同步。 但是,我们将不得不更新assert语句; 否则,它们也可能因有效条件而失败。 2 if (i %
   ...
}
    assert i % 2 == 1 : i;
    ...
}

断言を使用しない場合

1.公共メソッドのパラメータのチェック

ユーザーは公共メソッドのパラメータを提供できます。

したがって、これらのパラメータをチェックするために断言を使用する場合、条件が失敗しAssertionErrorが発生する可能性があります。

断言を使用するよりも、適切なランタイム例外を発生させ、それらを処理する方が良いです。

2.プログラム操作に影響を与える式の評価

断言条件下でプログラムの操作に影響を与える可能性のあるメソッドを呼び出したり、評価したりしないでください。

列の例として、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を削除しようと試みています。

断言が有効になっている場合、プログラムは正常に動作します。しかし、断言が無効になっている場合、リストから要素を削除しません。これによりプログラムが失敗する可能性があります。

結果を変数に割り当て、その変数を使用して断言を行います。

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を削除することができます。結果として、今後のプログラムの操作には影響しません。