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

Java 기본 튜토리얼

Java 흐름 제어

Java 배열

Java 동적 객체(I)

Java 동적 객체(II)

Java 동적 객체(III)

Java 예외 처리

Java 목록(List)

Java Queue(큐)

Java Map 집합

Java Set 집합

Java 입력/출력(I/O)

Java Reader/Writer

Java 다른 주제

Java 주장 (Assert)

이 튜토리얼에서는 예제를 통해 Java assert 문장(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 + " weekends ");
  }
}

출력 결과

이 주에 3 weekends

위의 출력을 얻는 이유는 프로그램이 컴파일 오류가 없고 기본적으로 주장이 비활성화되어 있기 때문입니다.

주장을 활성화하면 다음과 같은 출력을 얻습니다:

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 a week weekends";
    System.out.println("There are " + weekends.length + "  a week weekends");
  }
}

출력 결과

thread "main"에서 예외 발생 java.lang.AssertionError: There are only 2 a week weekends

위의 예제에서 보면, 표현식이 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!");
    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;
}

위의 스위치 문장은 일주일 중 날짜가 위와 같은 것들일 수 있다는 것을 나타냅니다.7중 하나의 값을 가지고 있습니다. 디폴트가 없는 것은 프로그래머가 이러한 상황 중 하나가 항상 실행될 것이라고 믿는 것입니다.

그러나, 일부 가정이 실제로 잘못된 경우에 대해서는 아직 고려하지 않았을 수 있습니다.

이러한 가정을 확인하기 위해 주장을 사용해야 합니다. 이렇게 하면 디폴트 스위치 조건에 도달하지 않도록 합니다.

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

dayOfWeek의 값이 유효한 날짜가 아니면 AssertionError를 발생시킵니다.

2가정을 기록합니다.

기본적인 가정을 기록하기 위해 많은 프로그래머들이 주석을 사용합니다. 예를 들어,

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

주장 대신 사용하십시오.

프로그램이 커질수록 주석은 낡고 동기화되지 않을 수 있습니다. 그러나 주장 문장을 업데이트하지 않으면, 유효한 조건으로 인해 실패할 수 있습니다.

if (i % 2 == 0) {
   ...
}
    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 요소를 제거하려고 시도합니다.

어플리케이션이 정상적으로 실행될 수 있도록 주장을 활성화하면 됩니다. 그러나, 주장을 비활성화하면 목록에서 요소를 제거하지 않을 수 있습니다. 이는 프로그램이 실패할 수 있습니다.

결과를 변수에 할당한 후, 그 변수를 사용하여 주어진 assert를 사용합니다.

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를 제거할 수 있도록 설정할 수 있습니다. 주어진 assert를 사용하지 않습니다. 결과적으로, 향후 프로그램 작업에 영향을 미치지 않습니다.