2011-01-17 3 views
13

나는 NullPointerException을 붙잡는 것이 나쁜 습관이라고 들었습니다. 나는 그것이 현명하게 그렇게 생각합니다. NullPointerException을 맨 위로 전파하면 잘못된 것으로 탐지 될 수 있습니다. 하지만 많은 사람들이 위의 코드에서 발생할 수있는 모든 종류의 예외에 대해 신경 쓰지 않아도되도록 많은 사람들이 직접 Exception을 잡는 것을 보았습니다. 이것은 좋은 습관입니까? 가장 잘 처리되지 않은 다른 종류의 예외는 무엇입니까? 그리고 우리가 예외 소스를 확신 할 수있는 특정 코드에 대해 NullPointerException을 처리하는 것은 나에게도 의미가 있습니다. 언제 예외를 처리해야하며 언제 처리해야합니까? 그리고 처리되지 않은 상태로 남아있는 예외의 가능한 목록은 무엇입니까?null 포인터 예외를 포착하는 것이 좋지 않은 경우 예외를 catch하는 것이 좋습니다.

+3

"나는 NullPointerException을 잡는 것이 나쁜 습관이라고 들었습니다. 나는 그것이 현명하게 생각합니다 .NullPointerException을 최상위로 전달하면 무언가가 잘못 감지 될 수 있습니다." "나에게 많은 의미가 없습니다. . 당신은 '삼키는'것을 '잡는'것을 혼란스럽게 생각하지 않습니까? – leonbloy

+2

'NullPointerException' 잡기와 함께 뭔가를하는 데는 아무런 문제가 없습니다. 이는 예외적 인 경우입니다. 일반적인 생각은 처리 할 수있는 예외를 잡아 내고 처리 할 수없는 예외를 포착 (포기)하지 않는 것입니다. 그래서 나는 당신이 들었던 것에 동의하지 않으면 안됩니다. –

답변

20

포켓몬 예외 처리가 잘못되었습니다. 특히 빈 블록 인 경우 단순히 삼키는 것입니다. 특정 상황에서 특정 사물을 실제로 의미한다는 이유로 특정 유형의 예외가 있습니다 (본질적으로 무엇이 잘못되었는지 알려주고 있음). 따라서 Exception을 붙잡음으로써 예외가 무엇인지 상관 없으며 어떤 일이 발생했는지 상관하지 않는다고 말하는 것입니다. 이것은 아마도 당신이 원하는 것이 아닙니다. 일반적으로

잡기 예외는 이러한 규칙을 수행 할 때 :
  • 가이 수준에서 예외를 처리하는 의미가 있습니까를? 그렇다면 그것을 처리하십시오. 그렇지 않다면 전파하십시오.
  • 첫 번째 규칙과 함께 "처리"는 또한 catch, wrapping 및 re-throwing을 의미 할 수 있습니다. 이는 추상화 누설을 방지하여 메서드 호출자가 기본 구현을 알 필요가 없도록하는 방법입니다.
  • 빈 catch 블록은 사용자가 예외를 처리 한 것을 의미하지 않습니다. 그것은 "삼키는"이라고 불립니다. 적어도 예외를 기록하고 싶습니다. 때때로 예외가 발생하는 것은 실제로 코드의 논리적 흐름의 일부이므로 예외적 인 작업을 원할 수 있습니다 (단, 규칙이 아닌 예외를 용서하십시오.) 예외를 발생시키는 상황을 확인하는 것이 좋습니다 코드의 논리적 흐름에 통합하는 것이 아니라).

코드에서 null 값을 쉽게 확인할 수 있으므로 null 포인터 예외를 명시 적으로 catch 할 필요가 없습니다. NullPointerException을 발생시키는 것은 의미가 없습니다 (나쁜 습관입니다). NullPointerException을 던지는 코드가 있고 제어 할 수없고 수정할 수없는 코드 인 경우에도 NullPointerException의 원인이되는 입력 매개 변수를 결정하고이를 구체적으로 테스트해야합니다.

잡을 수없는 또 다른 예외는 IllegalArgumentException입니다. 이 예외는 의미가없는 인수를 전달했음을 의미합니다. 이 예외를 잡는 대신 입력 매개 변수를 명시 적으로 테스트하여 정상적으로 작동하며 IllegalArgumentException을 발생시킬 수 없도록해야합니다.

+12

"포켓몬 예외 처리"란 무엇입니까? –

+25

catch (Exception ex) {모든 것을 잡으려는 경우입니다. –

+0

"Pokemon exception handling": 잡아라. 모두들 : D – tkr

5

그렇게함으로써 값을 추가 할 수있는 경우에만 예외를 catch해야합니다. 그렇지 않으면 발신자에게 전달해야합니다.

NullPointerException은 일반적으로 코드의 버그로 발생합니다. catch 블록에서이 문제를 어떻게 해결할 수 있습니까?

예외는 좋지 않습니다.

0

예외를 적절히 처리 할 수있는 좋은 방법이 있다면 호출자가 처리 할 수있는 좋은 방법이 있다는 희망이 아니라면 잡는 것이 유용합니다.

+1

그렇지 않으면 결국 예외가 기록 될 수 있습니다. –

1

예외를 포착하는 주된 규칙은 당신이 이것을하는 이유를 알아야한다는 것입니다. 예외 클래스는 프로그래머가 일반적인 오류 처리를 원할 때 발생하며 정확히 무슨 일이 일어 났는지 상관하지 않습니다. 주된 것은 뭔가 잘못되었습니다. 이 경우 그는 트랜잭션을 롤백하거나 정리를 결정할 수 있습니다. 특정 예외를 포착하는 경우 동일한 규칙을 적용하십시오. 나는 당신이 그 일을하는 이유를 정확히 알고 있습니다. 그러나 NPE의 경우 누군가 특별한 것을하고 싶어하는 경우는 매우 드뭅니다.

8

NullPointerException을 잡는 것이 나쁜 습관이라고 여겨지는 '이유'는 뭔가 잘못되었을 때 거품을 일으키기로되어 있기 때문이 아닙니다! 어떤 예외가 그 타입에 전적으로 기반하여 '처리되지 않은 최상의 상태'라고 말하는 것은 나쁜 생각처럼 보입니다.

NPE는 프로그래밍 오류의 결과로 간주됩니다. 엄격하게 올바른 프로그램은 절대 생성해서는 안됩니다. 그것이 잡히는 것을 보는 이유는 일반적으로 코드가 하나를 던져 버린 것을 의미하며, 프로그래머는 처음에 코드를 깨뜨린 코드를 수정하기보다는 그것을 잡아서 은폐하기로 결정했습니다.

예를 들어 내부적으로 버그가있는 API에 비즈니스 목적으로 결합되어 있고 때때로 널 포인터를 던진 경우이를 잡아 내거나 그것에 대해 조치를 취하거나 사용자에게 더 나은 정보를 제공하는 것이 합법적입니다 메시지. 누군가가 "Null Pointer Exception 잡기가 나쁜 것"이라고 말했기 때문에 'null'을 UI에 부딪치게하는 것은 의미가 없습니다!

캐칭 java.lang.Exception은 특정 경우에 합법적 일 수 있지만 일반적으로 "나는 게으르다"는 것은 아닙니다. :) 예를 들어 API를 구현하고 있고 사양에없는 예외가 나오지 않는다면 Exception을 잡아서 정의한 일부 애플리케이션 예외로 감쌀 수 있습니다.

3

일반적으로 예외를 catch해야하는 유일한시기는 의미있는 방식으로 처리 할 수있는 경우입니다. 당신이 할 수 없다면 당신은 단순히 그것을 위로 버블 링시키고 프로세스를 종료해야합니다. 예를 들어, NullPointerException 또는 I/O 오류로부터 의미있는 방식으로 복구 할 수 있습니까? 나는 그렇게 생각하지 않는다. 예외 처리에 대한

내 규칙 : 당신은 몇 가지 의미있는 방식으로 처리 할 수없는 한

일반적으로
  • 는, 예외를 포착하지 않습니다.
  • 프로세스/시스템 경계에서 예외를 캐치하고, 사용 가능한 모든 컨텍스트와 함께 캐치 된 예외를 기록한 다음 다시 던져 놓으십시오. 예외가 사용자 정의 예외 인 경우, 호출 프로세스에 대해 알려진/유용 한 유형의 예외로 랩핑하고이를 처리 할 수 ​​있습니다.
  • 대부분의 런타임 컨텍스트를 사용할 수있는 낮은 수준의 예외를 catch하고 예외 및 관련 컨텍스트를 로그 한 다음 예외를 다시 throw 할 수 있습니다.
  • 재실행시 throw caughtException ; 대신 throw ;을 사용하십시오. 이전 구문을 사용하면 원래 스택 추적이 유지됩니다. 후자 구문을 사용하면 throw caughtException ;으로 시작하는 새로운 스택 추적이 생성됩니다. 예외가 발견 된 지점까지 모든 컨텍스트와 호출 스택을 잃게됩니다.
  • 사용자가 원하는 경우 상위 수준에서 예외를 catch하고 정상적인 문제를 디버그하고 수정할 수 있도록 예외 정보를 로깅하여 프로세스를 정상적으로 종료 할 수 있습니다.

가능한 경우 흐름 제어 메커니즘으로 예외를 사용하지 마십시오. 예외는 사실상 예외적 인 것으로되어 있습니다.오히려 미리 호출하는 메소드에 대한 호출자의 계약 종료 (전제 조건)를 미리 적용하십시오.

자세한 내용은 Bertrand Meyers의 저서, Object Oriented Software Construction, 2nd ed.을 참조하십시오.

+1

"Rethrowing"에 대한 회신 : Java에서는 "throw"할 수 없다. "throw throw caughtException;" 그것을 할 때 당신은 스택 추적을 잃지 않습니다. – hjhill

관련 문제