Development Tip

예외 대 주장

yourdevel 2021. 1. 10. 19:41
반응형

예외 대 주장


Java 예외 처리와 assert조건 사용의 차이점은 무엇입니까 ?

Assert는 두 가지 유형으로 알려져 있습니다. 그런데 언제 assert키워드 를 사용해야 할까요?


코드 내의 내부 논리 검사에는 어설 션을 사용하고 즉각적인 코드의 제어를 벗어난 오류 조건에는 일반 예외를 사용하십시오.

어설 션은 켜고 끌 수 있다는 것을 잊지 마십시오. 인수 유효성 검사와 같은 것에 관심이 있다면 예외를 사용하여 명시 적이어야합니다. (그러나 해당 시점의 위반이 외부 오류가 아닌 내부 버그로 인한 것이라는 이유로 단언을 사용하여 개인 메서드 에 대한 인수 유효성 검사를 수행하도록 선택할 수 있습니다 .)

또는 모든 것에 예외를 사용하는 것이 합리적입니다 (IMO). 나는 개인적으로 단언을 전혀 사용하지 않지만 어느 정도 개인적인 선호의 문제입니다. (확실히 주장에 대한 객관적인 주장이있을 수 있지만, 선호도를 완전히 제거 할만큼 명확하지는 않습니다.)


Java 어설 션은 Java 예외 및 예외 처리 위에 구축됩니다. 실제로 Java 어설 션이 실패하면 결과는 다른 Java 예외처럼 포착 될 수있는 AssertionError 예외입니다. 예외와 어설 션의 주요 차이점은 다음과 같습니다.

  • 어설 션은 프로그래밍 오류, 즉 버그를 감지하는 수단으로 만 사용 하기위한 것 입니다. 대조적으로 예외는 다른 종류의 오류 또는 "예외"조건을 나타낼 수 있습니다. 예 : 잘못된 사용자 입력, 누락 된 파일, 힙 가득 참 등.
  • Java 언어는 assert명령문 형식으로 어설 션에 대한 구문 지원을 제공 합니다. 다음을 비교하십시오.

    if (x != y) {
         throw new SomeException("x != y");
    }
    
    assert x != y;
    
  • 가장 중요한 것은 Java를 사용하여 JVM을 시작할 때 전역 적으로 또는 개별 클래스에서 어설 션 검사를 활성화 또는 비활성화 할 수 있습니다.

참고 : 어떤 사람들은 항상 어설 션 검사를 끄고 프로덕션 코드를 실행 해야한다고 말합니다 . 나는 이것을 포괄적 인 진술로 동의하지 않는 경향이있다. 프로덕션 코드가 안정적인 것으로 알려져 있고 마지막 성능을 끌어 내야하는 경우 어설 션을 끄는 것이 좋습니다. 그러나 (예를 들어) 10 % 성능 저하가 실제 문제가 아니라면 대안이 계속되고 데이터베이스가 손상되면 어설 션 오류와 함께 응용 프로그램이 죽는 것을 선호합니다.

@Mario Ortegón은 이렇게 언급했습니다.

"꺼짐"은 잘 알려져 있지만 느린 알고리즘과 구현을 비교하여 최적화 된 알고리즘의 결과를 검증하는 데 어설 션을 사용할 수 있기 때문입니다. 따라서 개발 과정 O(N^3)에서 O(log N)알고리즘이 의도 한대로 작동 한다고 주장 하기 위해 해당 메서드를 호출하는 것이 좋습니다. 그러나 이것은 생산에서 원하지 않는 것입니다.

프로덕션에서 어설 션을 끄는 것이 좋은 관행 이라고 생각하든 그렇지 않든 , 활성화되었을 때 성능에 상당한 영향을 미치는 어설 션을 작성 하는 것은 확실히 나쁜 습관 입니다. 왜? 이는 더 이상 프로덕션 (문제 추적) 또는 스트레스 / 용량 테스트에서 어설 션을 활성화 할 수있는 옵션이 없음을 의미하기 때문입니다. 제 생각에는 O(N^3)사전 / 사후 조건 테스트 를 수행해야하는 경우 단위 테스트에서 수행해야합니다.


예외는 구현이 예상되거나 예상치 못한 오류없이 실행 중인지 확인하는 메커니즘입니다. 따라서 우리는 예외가 기본적으로 응용 프로그램을 실행하는 동안 예상치 못한 조건을 더 나은 방식으로 처리하는 데 사용되므로 예외를 효과적으로 사용하면 강력한 응용 프로그램이 생성됩니다.

어설 션은 응용 프로그램의 일부 기능 구현의 일부가되어서는 안됩니다. 그들은 가정을 검증하는 데만 사용해야합니다. 솔루션을 설계하는 동안 가정 한 내용이 실제로 실제로 유효한지 확인하기 위해서만 사용해야합니다.

참조 : http://geekexplains.blogspot.com/2008/06/asserions-in-java-assertions-vs.html


어설 션은 예외와 매우 유사합니다. 사실 예외와 마찬가지로 문제를 표시하지만 예외와 달리 대체 실행 경로를 제안하지는 않지만 단순히 실패합니다. 같은 일을 할 수 있다면 어설 션을 사용하는 이유는 무엇입니까?

문제가 해결되지 않아야 할 때 사용하고 실제로 첫 번째 장소에서 발생하지 않아야합니다. 처음에는 이상하게 들립니다. 모든 잠재적 인 문제로부터 코드를 보호하고 싶지 않습니까? 보통 그렇습니다. 하지만 그렇지 않은 경우가 있습니다. 이 경우를“계약에 의한 설계”라고합니다.

은행 신청서를 작성한다고 가정 해 보겠습니다. 개발자로서 가능한 모든 재정 상태를 지원할 수는 없습니다. 따라서 코딩을 시작하기 전에이 애플리케이션이 지원해야하는 유효한 범위를 제공하는 사양을 은행에서받습니다. 따라서 애플리케이션은 계약에 의해 설계됩니다 (은행의 사양에 따라). 이 계약은 응용 프로그램이 작동하기 위해 항상 참이어야하는 기본 원칙을 정의합니다. 이러한 기본 원칙을 "불변"이라고합니다 (변경할 수 없기 때문에). 계약에 의한 설계는 개발자로서의 삶을 단순화합니다. 계약에 정의 된 작업 범위를 지원할 책임 만 있습니다.
코드에서 이러한 불변의 값을 확인하는 것이 중요하지만 예외 인 것처럼 확인하고이를 해결하려고 시도해서는 안됩니다. 그들이 틀렸다면 입력이 계약상의 의무를 이행하지 않았기 때문에 실패해야합니다.

흥미로운 점은 중요한 위치에 단언을 입력하지 않고 불변성이 무효화되면 어쨌든 코드가 실패한다는 것입니다. 당신은 이유를 모를 것입니다. 요약하자면, 어설 션은 불변성을 확인하는 데 사용됩니다. 그들은 "계약에 의한 설계"원칙과 밀접한 관련이 있습니다. 문제를 디버깅하는 데 사용하므로 프로덕션에서 꺼져 있습니다.

또 다른 사용 사례 : 완전히 신뢰하지 않는 외부 라이브러리에 의존하는 경우 호출 할 때 assert 문을 사용할 수 있습니다.

Some also use assertions as a quick and dirty substitute for an exception (since its so easy to do), but conceptually that is not the proper thing to do.


Example of a good use of Assert:

assert flibbles.count() < 1000000; // too many flibbles indicate something is awry
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning

I personally think that Assert should only be used when you know something is outside desirable limits, but you can be sure it's reasonably safe to continue. In all other circumstances (feel free point out circumstances I haven't thought of) use exceptions to fail hard and fast.

The key tradeoff for me is whether you want to bring down a live/production system with an Exception to avoid corruption and make troubleshooting easier, or whether you have encountered a situation that should never be allowed to continue unnoticed in test/debug versions but could be allowed to continue in production (logging a warning of course).

cf. http://c2.com/cgi/wiki?FailFast see also my c# copy of this answer: Debug.Assert vs. Specific Thrown Exceptions


Assert is for debugging purpose only and its trigger condition should not happen (null pointer when there shouldn't be, etc.)

Exception is for special system events that may always happen : FileNotFound, ConnectionToServerLost, etc.


Assertion and Exception Handling both can assure programme correctness and avoid logic error,

but assertion can enable and disable as programmer wish,

in compiler if you use "java -ea JavaFileName" or "java -enableasserations JavaFileName" you can compile with assertion

if programmers don't need it ,"java -da JavaFileName " or "java -disableasserations JavaFileName " they can disable assertion.

this facility not in Exception handling


Assertion is used for debugging of the required assumptions to be checked at runtime only by enabling the assert feature while exception is to check the specific conditions to be checked during execution of the program to prevent the program from terminating.

ReferenceURL : https://stackoverflow.com/questions/1276308/exception-vs-assertion

반응형