자바 어설션 키워드는 무엇을 하며, 언제 사용해야 하는가?
주장들의 주요 역할을 이해하는 실제적인 예는 무엇인가?
(주장 키워드를 통한) 주장이 자바 1.4에 추가되었다.코드에서 불변성의 정확성을 검증하는 데 사용된다.그것들은 결코 생산 코드에 트리거되어서는 안 되며, 코드 경로의 버그나 오용을 나타낸다.Run-time에서 를 통해 활성화할 수 있다.-ea
에 대한 옵션java
명령어를 사용하지만 기본적으로 설정되지 않음.
예:
public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;
return result;
}
원자력 발전소를 통제하는 프로그램을 작성해야 한다고 가정해 봅시다.아무리 사소한 실수라도 재앙적인 결과를 초래할 수 있다는 것은 매우 명백하다. 따라서 당신의 코드는 버그리스(bug-free)여야 한다(논쟁을 위해 JVM이 버그리스(bug-free)라고 가정함).
자바는 검증 가능한 언어가 아니다. 즉, 당신은 당신의 수술 결과가 완벽할 것이라고 계산할 수 없다.이것의 주된 이유는 포인터가 어디에 있든 어디든 포인터를 가리킬 수 있기 때문이다. 따라서 포인터는 적어도 코드의 합리적인 범위 내에서는 이 정확한 값의 값으로 계산될 수 없다.이 문제를 고려할 때, 당신의 코드가 전체적으로 옳다는 것을 증명할 방법이 없다.하지만 당신이 할 수 있는 것은 적어도 그것이 일어났을 때 모든 벌레를 발견한다는 것을 증명하는 것이다.
이 아이디어는 DbC(Design-by-Contract) 패러다임에 기초한다. 먼저 (수학적 정밀도로) 방법을 정의한 다음 실제 실행 중에 테스트하여 검증한다.예:
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
return a + b;
}
이것이 잘 작동한다는 것은 꽤 명백하지만, 대부분의 프로그래머들은 이 안에 숨겨진 버그를 보지 못할 것이다(힌트: Ariane V가 비슷한 버그 때문에 추락했다).이제 DbC는 함수의 입력과 출력을 항상 확인하여 제대로 작동하는지 확인해야 한다고 정의한다.Java는 다음과 같은 주장을 통해 이를 수행할 수 있다.
// Calculates the sum of a (int) + b (int) and returns the result (int).
int sum(int a, int b) {
assert (Integer.MAX_VALUE - a >= b) : "Value of " + a + " + " + b + " is too large to add.";
final int result = a + b;
assert (result - a == b) : "Sum of " + a + " + " + b + " returned wrong sum " + result;
return result;
}
만약 이 기능이 지금 실패한다면, 당신은 그것을 알아차릴 것이다.코드에 문제가 있다는 것을 알게 될 것이고, 코드의 위치를 알게 될 것이며, 코드의 원인이 무엇인지 알게 될 것이다(예외와 유사).그리고 더욱 중요한 것은 잘못된 가치로 작용하는 더 이상의 코드를 방지하고 그것이 통제하는 모든 것에 손상을 입힐 수 있는 일이 발생할 때 올바른 실행을 중지하는 것이다.
자바 예외도 비슷한 개념이지만 모든 것을 검증하지 못한다.(실행 속도에 따라) 더 많은 검사를 하려면 주장을 사용할 필요가 있다.그렇게 하면 코드가 부풀어오르지만, 결국 놀랄 만큼 짧은 개발 시간(버그를 빨리 고칠수록 비용이 적게 든다)에 제품을 납품할 수 있다.게다가, 만약 당신의 코드 안에 어떤 버그가 있다면, 당신은 그것을 감지할 것이다.벌레가 미끄러져 나중에 문제를 일으킬 방법은 없다.
이것은 여전히 버그프리 코드에 대한 보장은 아니지만, 그것은 일반적인 프로그램보다 훨씬 더 가깝다.
주장은 당신의 코드에서 버그를 잡기 위한 개발 단계 도구다.그것들은 쉽게 제거되도록 설계되어 있어서 생산 코드에 존재하지 않을 겁니다.따라서 주장은 고객에게 제공하는 "솔루션"의 일부가 아니다.그들은 당신이 만들고 있는 가정이 맞는지 확인하기 위한 내부 점검이다.가장 일반적인 예는 null을 검사하는 것이다.많은 방법들이 다음과 같이 쓰여 있다.
void doSomething(Widget widget) {
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
이런 방법에서는 위젯이 절대 null이 되어서는 안 된다.그러니까 그게 무효라면 코드 어딘가에 추적해야 할 버그가 있다는 거군그러나 위의 암호는 결코 이것을 말해주지 않을 것이다.그래서 "안전한" 코드를 쓰려는 선의의 노력으로, 당신도 버그를 숨기고 있는 것이다.이렇게 코드를 쓰는 것이 훨씬 낫다.
/**
* @param Widget widget Should never be null
*/
void doSomething(Widget widget) {
assert widget != null;
widget.someMethod(); // ...
... // do more stuff with this widget
}
이렇게 하면 반드시 이 벌레를 일찍 잡을 수 있을 것이다.(계약서에 이 매개변수가 null이 되어서는 안 된다고 명시하는 것도 유용하다.)개발 중에 코드를 테스트할 때는 반드시 주장을 켠다.(그리고 동료들에게 이 일을 하도록 설득하는 것도 종종 어려운 일인데, 나는 매우 성가신 일이라고 생각한다.
이제, 당신의 동료들 중 일부는 생산에서 예외를 막기 위해 여전히 무효 수표를 넣어야 한다고 주장하며 이 코드에 반대할 것이다.그 경우, 그 주장은 여전히 유용하다.이렇게 쓰면 된다.
void doSomething(Widget widget) {
assert widget != null;
if (widget != null) {
widget.someMethod(); // ...
... // do more stuff with this widget
}
}
이런 식으로 동료들은 생산 코드에 대한 무효확인서가 있다는 사실에 기뻐하겠지만, 개발 중에는 위젯이 무효일 때 버그를 더 이상 감출 수 없게 된다.
실제 예는 다음과 같다.나는 평등을 위해 두 임의의 값을 비교하는 방법을 쓴 적이 있는데, 여기서 두 값은 모두 null일 수 있다.
/**
* Compare two values using equals(), after checking for null.
* @param thisValue (may be null)
* @param otherValue (may be null)
* @return True if they are both null or if equals() returns true
*/
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = thisValue.equals(otherValue);
}
return result;
}
이 코드는 의 작업을 위임한다.equals()
이 값이 null이 아닌 경우 방법.그러나 그것은 다음과 같이 가정한다.equals()
방법이 의 계약을 정확히 이행하다equals()
null 매개 변수를 적절하게 처리하여
한 동료가 우리 수업의 많은 부분이 버그가 있다고 말하면서 내 코드에 반대했다.equals()
무효 테스트가 되지 않는 방법들, 그래서 나는 이 방법에 수표를 넣어야 한다.이것이 현명한 것인지, 아니면 우리가 그 오류를 억지로라도 찾아내어 고칠 수 있는 것인지는 논쟁의 여지가 있지만, 나는 동료에게 미루어 무효 수표를 넣었는데, 나는 다음과 같이 코멘트로 표시했다.
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
} else {
result = otherValue != null && thisValue.equals(otherValue); // questionable null check
}
return result;
}
추가 수표는,other != null
는 경우에만 필요하다.equals()
메서드는 계약에서 요구하는 null을 검사하지 않는다.
버기코드를 우리의 코드 베이스에 머물게 하는 지혜에 대해 동료와 무과실 논쟁을 벌이기보다는, 나는 단순히 코드에 두 가지 주장을 집어넣었다.이 주장들은 개발 단계에서 우리 반 중 하나가 실행하지 못하면 나에게 알려줄 것이다.equals()
내가 고칠 수 있게 말이야
public static boolean compare(final Object thisValue, final Object otherValue) {
boolean result;
if (thisValue == null) {
result = otherValue == null;
assert otherValue == null || otherValue.equals(null) == false;
} else {
result = otherValue != null && thisValue.equals(otherValue);
assert thisValue.equals(null) == false;
}
return result;
}
명심해야 할 중요한 사항은 다음과 같다.
주장은 개발 단계 도구일 뿐이다.
주장의 요점은 코드뿐만 아니라 코드 베이스에도 버그가 있는지 알려 주는 것이다.(이러한 주장은 사실상 다른 계급의 벌레에 기표를 할 것이다.)
비록 동료가 우리의 수업이 제대로 쓰여졌다고 확신한다고 해도, 이곳의 주장은 여전히 유용할 것이다.null 테스트에 실패할 수 있는 새로운 클래스가 추가될 것이며, 이 방법은 우리를 위해 이러한 버그에 플래그를 표시할 수 있다.
개발에서는 자신이 작성한 코드가 주장을 사용하지 않더라도 항상 주장을 켜야 한다.내 IDE는 새로운 실행 파일에 대해 항상 기본적으로 이 작업을 수행하도록 설정되어 있다.
단언은 생산에 있어서 코드의 행동을 바꾸지 않기 때문에 동료는 무효 수표가 거기에 있고, 이 방법이 설사 그 방법이 제대로 실행된다고 기뻐하고 있다.
equals()
방법은 버그다.나는 아무 마차나 잡을 것이기 때문에 행복하다.equals()
개발의 방법
또한, 당신은 로그 파일이나 출력 스트림의 스택 추적을 통해 통지받을 수 있도록, 당신은 당신의 어설션 정책을 테스트해야 한다.
어설션(Assent)은 언제 사용해야 하는가?
많은 좋은 답변이 무엇을 설명하는지.assert
키워드는 그렇지만, "언제 키워드를 실생활에서 사용해야 하는가?"라는 진짜 질문에 대답하는 사람은 거의 없다.정답:
거의 없다
어떤 개념으로 주장한다는 것은 멋진 일이다.좋은 코드는 많은 것을 가지고 있다.if (...) throw ...
(그리고 그들의 친척들은 다음과 같은 진술들Objects.requireNonNull
그리고Math.addExact
그러나, 특정 설계 결정으로 인해 이 시스템의 효용성이 크게 제한되었다.assert
키워드 자체
그 이면의 운전 아이디어는assert
키워드는 조기 최적화로, 주요 기능은 모든 점검을 쉽게 끌 수 있다는 것이다.사실 수표는 기본적으로 꺼져 있다.
그러나 불변 점검은 생산에서 계속 이루어지는 것이 매우 중요하다.이는 완벽한 시험 적용 범위가 불가능하고 모든 생산 코드에 버그가 있을 것이기 때문에 이러한 주장이 진단 및 완화에 도움이 되어야 한다.
따라서, 의 사용.if (...) throw ...
값IllegalArgumentException
.
때때로, 사람들은 원하지 않을 정도로 오랜 시간이 걸리는 불변 수표를 쓰고 싶어할 수도 있다.그러나 그러한 점검은 시험을 느리게 할 것이며 이는 바람직하지 않다.이러한 시간 소모적인 점검은 보통 단위 시험으로 작성된다.그럼에도 불구하고, 때때로 사용하는 것이 이치에 맞을 수도 있다.assert
이런 이유로
사용 안 함assert
단순히 보다 깨끗하고 예쁘기 때문에.if (...) throw ...
(그리고 나는 깨끗하고 예쁜 것을 좋아하기 때문에 아주 고통스럽게 그렇게 말한다.)만약 당신이 단지 당신 자신을 도울 수 없고 당신의 응용프로그램이 어떻게 시작되었는지 제어할 수 있다면, 자유롭게 사용하라.assert
그러나 항상 생산에 있어서 주장을 가능하게 한다.물론, 이것은 내가 하는 경향이 있다.나는 lombok 주석을 추진하고 있다.assert
처럼 if (...) throw ...
여기서 투표하십시오.
(Rant: JVM devs는 형편없고, 시기상조적으로 최적화한 코드 사용자들이었다.그래서 Java 플러그인과 JVM에서 많은 보안 문제에 대해 듣게 되는 것이다.그들은 생산 코드에 기본적인 견제와 주장을 포함하기를 거부했고, 우리는 계속해서 가격을 지불하고 있다.)
가장 일반적인 사용 사례는 다음과 같다.열거형 값을 켠다고 가정합시다.
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
}
네가 모든 사건을 처리하는 한, 넌 괜찮아하지만 언젠가 누군가가 당신의 열거형에 무화과를 첨가하고 그것을 당신의 스위치 문장에 추가하는 것을 잊어버릴 것이다.이것은 당신이 스위치 문을 떠난 후에야 효과를 느낄 수 있기 때문에 잡기가 까다로워질 수 있는 버그를 만들어낸다.그러나 이렇게 스위치를 쓰면 바로 잡을 수 있다.
switch (fruit) {
case apple:
// do something
break;
case pear:
// do something
break;
case banana:
// do something
break;
default:
assert false : "Missing enum value: " + fruit;
}
주장은 사후 조건과 "절대 실패해서는 안 된다"는 전제 조건을 확인하는 데 사용된다.올바른 코드는 어떤 주장을 어길 수 없으며, 그것들이 촉발할 때 버그(문제의 실제 위치가 가까운 곳에서 희망적으로)를 나타내야 한다.
주장의 예로는 특정 방법 그룹이 올바른 순서로 호출되는지 확인하는 것일 수 있다(예: 다음과 같다).hasNext()
전에 불려지다next()
의 한 곳에.Iterator
).
자바에서 어설션 키워드는 무엇을 하는가?
컴파일된 바이트코드를 봅시다.
우리는 다음과 같이 결론짓는다.
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
다음과 거의 동일한 바이트 코드를 생성한다.
public class Assert {
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
어디에Assert.class.desiredAssertionStatus()
이다true
할 때-ea
명령줄을 통해 전달되며 그렇지 않으면 거짓이다.
우리는 사용한다.System.currentTimeMillis()
최적화되지 않도록 하기 위해 (assert true;
했다.
Java가 호출만 하면 되도록 합성 필드가 생성됨Assert.class.desiredAssertionStatus()
로딩 시간에 한 번, 그리고 결과를 거기에 저장한다.참고 항목:"정적 합성"의 의미는 무엇인가?
다음을 통해 검증할 수 있다.
javac Assert.java
javap -c -constants -private -verbose Assert.class
Oracle JDK 1.8.0_45에서는 합성 정적 필드가 생성되었다(참조:"정적 합성"의 의미는 무엇인가?:
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
정적 이니셜라이저와 함께:
0: ldc #6 // class Assert
2: invokevirtual #7 // Method java/lang Class.desiredAssertionStatus:()Z
5: ifne 12
8: iconst_1
9: goto 13
12: iconst_0
13: putstatic #2 // Field $assertionsDisabled:Z
16: return
주요 방법은 다음과 같다.
0: getstatic #2 // Field $assertionsDisabled:Z
3: ifne 22
6: invokestatic #3 // Method java/lang/System.currentTimeMillis:()J
9: lconst_0
10: lcmp
11: ifeq 22
14: new #4 // class java/lang/AssertionError
17: dup
18: invokespecial #5 // Method java/lang/AssertionError."<init>":()V
21: athrow
22: return
결론은 다음과 같다.
- 에 대한 바이트 코드 수준 지원이 없음
assert
이다: 자자어다. assert
시스템 속성으로 에뮬레이션을 잘 할 수 있음-Pcom.me.assert=true
대신하여-ea
지휘선상에, 그리고throw new AssertionError()
.
주장은 코드의 결함을 탐지하는 것을 허용한다.프로그램이 실행 중일 때 테스트 및 디버깅을 중단한 상태에서 테스트 및 디버깅에 대한 주장을 설정할 수 있다.
그것이 사실이라는 것을 알면서 왜 주장하는가?모든 것이 제대로 작동해야 비로소 진실이다.프로그램에 하자가 있는 경우 실제로 사실이 아닐 수 있다.그 과정에서 이것을 감지하는 것은 무언가 잘못되었다는 것을 알게 해준다.
안assert
문에는 선택사항과 함께 이 문장이 포함되어 있다.String
메세지.
주장문의 구문에는 두 가지 형태가 있다.
assert boolean_expression;
assert boolean_expression: error_message;
주장을 사용해야 하는 곳과 주장하지 말아야 하는 곳을 규정하는 몇 가지 기본적인 규칙들이 여기에 있다.주장은 다음을 위해 사용되어야 한다.
개인 메서드의 입력 매개 변수 검증.공개적인 방법에는 해당되지 않는다.
public
방법은 나쁜 매개변수를 통과할 때 규칙적인 예외를 두어야 한다.거의 확실히 사실인 사실의 타당성을 보장하기 위한 프로그램 어디든.
예를 들어, 1 또는 2만 될 것이라고 확신할 경우 다음과 같은 주장을 사용할 수 있다.
...
if (i == 1) {
...
}
else if (i == 2) {
...
} else {
assert false : "cannot happen. i is " + i;
}
...
- 모든 방법의 끝에서 사후 조건 검증.즉, 사업논리를 실행한 후, 자신의 변수나 결과의 내부 상태가 당신이 기대하는 것과 일치하도록 하는 주장을 사용할 수 있다.예를 들어 소켓이나 파일을 여는 방법은 끝에 있는 어설션을 사용하여 소켓이나 파일이 실제로 열리는지 확인할 수 있다.
다음과 같은 경우에는 주장을 사용해서는 안 된다.
공용 메서드의 입력 매개 변수 유효성 검사.주장이 항상 실행되는 것은 아니기 때문에 정기적인 예외 메커니즘을 사용해야 한다.
사용자가 입력한 항목에 대한 제약 조건 확인위와 같다.
부작용에 사용해서는 안 된다.
예를 들어, 여기서 주장이 의사 소명의 부작용에 사용되기 때문에 이것은 적절한 용도가 아니다.doSomething()
방법
public boolean doSomething() {
...
}
public void someMethod() {
assert doSomething();
}
이러한 주장이 정당화될 수 있는 유일한 경우는 코드에 주장이 활성화되어 있는지 여부를 확인하려고 할 때 뿐이다.
boolean enabled = false;
assert enabled = true;
if (enabled) {
System.out.println("Assertions are enabled");
} else {
System.out.println("Assertions are disabled");
}
스택 클래스의 실제 예(Java 문서의 어설션)
public int pop() {
// precondition
assert !isEmpty() : "Stack is empty";
return stack[--num];
}
여기에 제공된 모든 훌륭한 답변 외에도, 공식 Java SE 7 프로그래밍 가이드는 사용법에 대한 매우 간결한 매뉴얼을 가지고 있다.assert
; 주장을 사용하는 것이 좋은 아이디어일 때(그리고 중요한 것은 나쁜 아이디어일 때), 그리고 예외를 두는 것과 어떻게 다른지에 대한 몇 가지 구체적인 예를 들 수 있다.
단언은 발달할 때 매우 유용하다.당신의 코드가 제대로 작동한다면 어떤 일이 일어날 수 없을 때 당신은 그것을 사용한다.그것은 사용하기 쉽고, 실생활에서 꺼질 것이기 때문에 영원히 코드에 머무를 수 있다.
만약 그 상태가 실생활에서 일어날 수 있는 가능성이 조금이라도 있다면, 당신은 그것을 다루어야 한다.
좋아하지만 Eclipse/Android/ADT에서 어떻게 켜야 할지 모르겠어. 디버깅할 때도 꺼져 있는 것 같아. (이것에는 스레드가 있지만 ADT Run Configuration에는 나타나지 않는 'Java vm'을 가리킨다.)
다음은 최대 절전 모드/SQL 프로젝트를 위해 서버에 작성한 주장이다.엔티티 빈은 isActive 및 isDefault라는 두 개의 유효 부울 속성을 가지고 있다.각각 "N"으로 처리된 "Y" 또는 "N" 또는 null 값을 가질 수 있다. 브라우저 클라이언트가 이 세 가지 값으로 제한되는지 확인하고자 한다.그래서 이 두 가지 특성에 대한 나의 세터에서는 다음과 같은 주장을 추가했다.
assert new HashSet<String>(Arrays.asList("Y", "N", null)).contains(value) : value;
다음 사항에 유의하십시오.
이 주장은 단지 개발 단계만을 위한 것이다.만약 고객이 나쁜 값을 보낸다면, 우리는 생산에 도달하기 훨씬 전에 그것을 일찍 잡아 고칠 것이다.주장은 일찍 잡을 수 있는 결함에 대한 것이다.
이 주장은 느리고 비효율적이다.괜찮아주장은 느릴 자유가 있다.우리는 그것들이 개발 전용 도구이기 때문에 신경 쓰지 않는다.이것은 주장이 불가능하기 때문에 생산 코드의 속도를 늦추지 않을 것이다.(이 점에 대해서는 약간의 이견이 있어, 나중에 이야기하도록 하겠다.)이것은 나의 다음 요점으로 이어진다.
이 주장은 부작용이 없다.나는 수정 불가능한 정적 최종 세트와 나의 가치를 시험할 수 있었지만, 그 세트는 결코 사용되지 않는 생산에 머물러 있었을 것이다.
이 주장은 클라이언트의 적절한 작동을 검증하기 위해 존재한다.그래서 생산에 도달할 때쯤에는 의뢰인이 제대로 작동하고 있다는 것을 확신하게 될 것이고, 따라서 주장을 안전하게 끌 수 있을 것이다.
어떤 사람들은 이렇게 묻는다.생산에 있어서 주장이 필요하지 않다면, 일이 끝나면 그냥 꺼내지 그래?왜냐하면 당신이 다음 버전을 작업할 때 그것들이 여전히 필요할 것이기 때문이다.
어떤 사람들은 모든 벌레들이 사라졌다고 절대 확신할 수 없기 때문에 생산 중에도 벌레들을 곁에 둘 필요가 있기 때문에 절대로 주장을 해서는 안 된다고 주장해왔다.그래서 주장할 수 있는 유일한 장점은 그것들을 끌 수 있다는 것이기 때문에 주장할 필요가 없다.그러므로, 이러한 생각에 따르면, 당신은 절대 주장을 해서는 안 된다.동의하지 않습니다.만약 테스트가 생산에 속한다면, 당신은 주장을 해서는 안 된다는 것은 확실하다.그러나 이 시험은 생산에 속하지 않는다.이것은 절대로 생산에 도달할 것 같지 않은 벌레를 잡기 위한 것이므로, 당신이 완성했을 때 안전하게 꺼질 수 있다.
BTW, 이렇게 쓸 수도 있었는데.
assert value == null || value.equals("Y") || value.equals("N") : value;
이것은 3개의 값만 있어도 괜찮지만, 가능한 값의 수가 많아지면 해시세트 버전이 더욱 편리해진다.나는 효율성에 대한 나의 요점을 설명하기 위해 HashSet 버전을 선택했다.
주장은 꺼질 수 있는 점검이다.거의 사용하지 않아. 왜?
- 공법 논쟁에 대한 통제가 없기 때문에 공법 논쟁들을 확인하는 데 사용되어서는 안 된다.
- 다음과 같은 간단한 점검에 사용해서는 안 된다.
result != null
그런 수표가 매우 빠르고 저축할 것이 거의 없기 때문에.
그럼, 남은 건?조건에 대한 값비싼 수표는 정말 사실일 것으로 예상된다.좋은 예는 RB-트리 같은 데이터 구조의 불변성일 것이다.사실, 인ConcurrentHashMap
의 '가르지만'에 몇 있는 TreeNodes
.
- 당신은 그들이 달리기 시간을 쉽게 지배할 수 있기 때문에 생산에서 그것들을 켜는 것을 정말 원하지 않는다.
- 테스트 중에 전원을 켜거나 끄십시오.
- 코드 작업 시 반드시 전원을 켜십시오.
가끔, 수표가 정말 비싸지 않을 때도 있지만, 동시에, 여러분은 그것이 통과될 것이라고 확신할 수 있다.내 코드에는 예를 들어
assert Sets.newHashSet(userIds).size() == userIds.size();
내가 방금 만든 리스트가 독특한 요소를 가지고 있다고 확신하지만, 나는 그것을 문서화하고 다시 확인하고 싶었다.
재점검(Java뿐만 아니라 여러 언어에서도 해당됨):
"디버깅"은 주로 디버깅 프로세스 동안 소프트웨어 개발자들에 의해 디버깅 보조 도구로 사용된다.주장 메시지는 절대 나타나서는 안 된다.많은 언어가 "프로덕션" 코드를 생성하는 데 사용하기 위해 모든 "어세서"를 무시하게 하는 컴파일 시간 옵션을 제공한다.
논리 오류를 나타내든 말든 모든 종류의 오류 조건을 처리하는 데 편리한 방법은, 만약 여러분이 계속할 수 없는 오류 조건과 마주친다면, 여러분은 단순히 여러분이 있는 곳 어디에서나 오류 조건들을 "공중에 던질" 수 있고, 다른 누군가가 그것들을 "공중시킬" 준비가 되어 있기를 기대하기 때문이다.통제는 예외를 던진 코드에서 곧장 포수의 미트까지 한 걸음으로 옮겨진다.(그리고 포수는 일어났던 전화의 완전한 뒷추적을 볼 수 있다)
게다가, 서브루틴의 호출자들은 서브루틴이 성공했는지 여부를 확인할 필요가 없다: "만약 우리가 지금 여기에 있었다면, 서브루틴은 성공했을 것이다. 그렇지 않았다면 그것은 예외를 던졌을 것이고 우리는 지금 여기에 없을 것이기 때문이다!"이 간단한 전략은 코드 설계와 디버깅을 훨씬 더 쉽게 만든다.
예외는 "규칙에 대한 예외"와 같은 치명적인 오류 조건을 편리하게 허용한다.그리고, "규칙의 예외"인 코드 경로로 그들을 처리하려면..."플라이볼!"
여기 또 다른 예가 있다.나는 두 개의 정렬된 배열에서 값의 중위수를 찾는 방법을 썼다.메소드는 배열들이 이미 정렬되었다고 가정한다.성능상의 이유로 어레이를 먼저 정렬하거나 어레이가 정렬되었는지 확인조차 해서는 안 된다.하지만, 이 방법을 정돈되지 않은 데이터로 부르는 것은 심각한 버그인데, 우리는 개발 단계에서 이 버그들이 일찍 잡히기를 원한다.그래서 이렇게 상반되는 것 같은 목표를
public static int medianOf(int[] a, int[] b) {
assert assertionOnlyIsSorted(a); // Assertion is order n
assert assertionOnlyIsSorted(b);
... // rest of implementation goes here. Algorithm is order log(n)
}
public static boolean assertionOnlyIsSorted(int[] array) {
for (int i=1; i<array.length; ++i) {
if (array[i] < array[i-1]) {
return false;
}
return true;
}
}
이렇게 해서 느리게 진행되는 시험은 벌레를 잡는 것보다 속도가 덜 중요한 개발단계에서만 진행된다.당신은 그것을 원한다.medianOf()
rogh(n) 을은 을, "정렬"은 order서, "정렬"은 순서 neiga이다.그래서 나는 그것을 어떤 주장 안에 넣었고, 그것의 사용을 개발 단계로 제한하기 위해, 그리고 나는 그것이 생산에 적합하지 않다는 것을 분명히 하는 이름을 붙였다.
이렇게 하면 나는 양쪽의 장점을 모두 가질 수 있다.개발 과정에서 이것을 잘못 부르는 어떤 방법이든 잡히고 고쳐질 것이라는 것을 알고 있다.그리고 나는 그렇게 하기 위한 느린 테스트가 생산 실적에 영향을 미치지 않을 것이라는 것을 알고 있다.(생산에서는 주장을 보류하고, 개발에서는 이를 켜려고 하는 이유를 잘 보여주는 그림이기도 하다.)
주장은 기본적으로 응용프로그램을 디버깅하기 위해 사용되거나 응용 프로그램의 유효성을 확인하기 위해 일부 응용 프로그램에 대한 예외 처리를 대체하기 위해 사용된다.
주장은 런타임에 통한다.전체 개념을 매우 간단하게 설명할 수 있는 간단한 예는 다음과 같다. 자바에서 주장 키워드는 무엇을 하는가? (WikiAnswers)이다.
주장은 기본적으로 비활성화되어 있다.이 프로그램을 활성화하려면 다음을 사용하여 프로그램을 실행해야 한다.-ea
옵션(선택 사항은 다양할 수 있음).예를 들어,java -ea AssertionsDemo
.
주장을 사용하기 위한 두 가지 형식이 있다.
- 단순함: 예.
assert 1==2; // This will raise an AssertionError
. - 더 나은 방법:
assert 1==2: "no way.. 1 is not equal to 2";
이렇게 하면 주어진 메시지와 함께 AssertionError가 발생하므로 더 좋다.비록 실제 구문은assert expr1:expr2
expr2가 값을 반환하는 어떤 표현일 수 있는 곳에서, 나는 단지 메시지를 인쇄하기 위해 그것을 더 자주 사용했다.
기본적으로 "Assert true"는 통과하고 "Assert false"는 실패할 것이다.이 기능이 어떻게 작동하는지 살펴봅시다.
public static void main(String[] args)
{
String s1 = "Hello";
assert checkInteger(s1);
}
private static boolean checkInteger(String s)
{
try {
Integer.parseInt(s);
return true;
}
catch(Exception e)
{
return false;
}
}
assert
키워드 입니다.JDK 1.4에 소개되었다.는 두 종류의 것이다.assert
s
- 매우 간단하다
assert
- 심플
assert
진술들
기본적으로 모두assert
진술은 실행되지 않을 것이다.만약assert
진술이 거짓을 수신하면 자동으로 주장 오류가 발생한다.
'programing' 카테고리의 다른 글
vue의 로컬 저장소에 값을 추가하는 방법 (0) | 2022.05.03 |
---|---|
webpack.config.babel에서 '가져오기'를 사용하는 중 오류 발생.js (0) | 2022.05.03 |
vuej에 이미지 파일로 div 저장 (0) | 2022.05.03 |
vuex의 동적 변수에 대한 속성을 보는 방법 (0) | 2022.05.03 |
Vue 앱 배포 시 기본 경로를 변경하는 방법 (0) | 2022.05.03 |