2012-11-22 2 views
6

C# 입문서에서 무엇을해야할지 모르는 경우에는 예외를 잡지 말아야한다는 것을 읽었습니다. Java에서 프로그래밍 할 때 약간의 조언을 생각하면, 예외 상황을 어떻게 처리해야할지 모르지만, 컴파일 오류를 피하기 위해 "catch"하거나 "percolate"해야합니다. 나는 차라리 throws 절을 가진 메서드를 복잡하게하지 않을 것이다. 그래서 나는 종종 다음과 같이 RuntimeException에 대한 예외를 "변환"하는 것에 의지했다. throws 절을 실제로 "처리"(적절하게 처리되지 않음) 예외에 대한 많은 메소드에 추가하는 것은 장황하고 혼란스럽게 보입니다. 다음과 같은 나쁜 스타일이 있습니까? 그렇다면이 문제를 해결하는 더 좋은 방법은 무엇입니까?치명적인 예외 처리

try { 
    thread.join(); 
} 
catch (InterruptedException e) { 
     Console.printwriter.format("%s\n", e.printStackTrace()); 
    throw new RuntimeException(); 
} 

편집 : 당신은 아마 불필요한 throws 조항으로 끝낼 코드 수정 후 : 제외 혼란에서의 관류 예외 또 다른 문제가있다. 내가 그들을 청소하는 법을 알기위한 유일한 방법은 시행 착오이다 : 그것을 제거하고 컴파일러가 불평하는지 확인한다. 당신이 코드를 깨끗하게 유지하고 싶다면 분명히, 이것은 성가신 일이다.

+0

더 나은 방법은 예외를 지속적으로 던지지 않아도되는 방식으로 코드를 작성하는 것입니다. – lifetimes

+0

동의. 나는 일반적으로 새로 정의 된 예외를 많이 선언하지 않습니다. 저는 주로 제 3 자 및 Java 예외에 대해 우려하고 있습니다. – H2ONaCl

+0

@ user1394965 예, 코드에서 예외가 "지속적으로"발생해서는 안됩니다. 그러나 예외가 가능한지 여부는 매우 다른 문제입니다. 입출력 조작이나 블로킹 방법을 포함한 모든 작업은 피할 수없는 예외 처리로 인해 어려움을 겪을 수 있습니다. –

답변

5

체크 된 예외와 확인되지 않은 예외 사이의 Java 구분은 somewhat controversial입니다.

인터페이스를 제어하는 ​​경우 일반적으로 서명에 throws 절을 추가하는 것이 가장 좋습니다.

예외를 처리 할 수는 없지만 검사 된 예외 서명으로 인해 거품을 일으키지 못하는 상황에 처한 경우 (예외적으로 RuntimeException을 던질 수 있음) 예외를 래핑하면, 일반적인 관행입니다.

많은 경우 IOException 또는 SQLException과 같은 다른 확인 예외를 사용하고자 할 수 있습니다. 그러나 이것이 항상 선택 사항은 아닙니다. 이 또한 예외를 처리 할 수있는 사람에게 지연 될 수 있기 때문에 이것은 또한 (로깅의 필요성을 제거 할 수 있습니다

throw new RuntimeException(e); 

:

하지만 당신의 예제에서

는 "원인"로 원래의 예외를 포함 모든 정보는 여전히 존재합니다).

1

예외에 대한 처리 방법을 모르는 경우에는 잡아서는 안됩니다. 따라서 메소드는 이제 예외를 throw하므로 런타임 예외가 아닌 경우 throws 절이 있어야합니다. 그들에게 아무 문제가 없습니다.

+0

@broiyan 예, 정상적인 예외 사항을 다루는 귀하의 질문과 관련하여 답변을 드리고자합니다. – Pablo

1

나는 Joshua Bloch의 Effective Java 2 판 - 에있는 조언을 좋아한다. 추상화 (항목 61)에 적절한 예외를 던집니다.

즉, 메서드에서 "제거"하려고하는 일련의 예외에 직면했을 때 예외를 메서드에 대해 더 의미있는 의미로 재 포장해야하는지 고려해야합니다.

그런 접근법은 여러 개의 하위 예외를 하나의 상위 예외로 결합하는 즐거운 부작용을 종종 가지고 있습니다.

+0

그게 좋은 생각입니다. – H2ONaCl

+0

던져진 예외를 단순화하는 이점과 코드 기반을 부풀게하는 수백 가지의 사용자 정의 예외를 발명하는 이점 사이의 균형 잡힌 행동입니다. –

1

훌륭한 프로그래밍 방법을 사용하면 호출자로부터 개체의 내부 상태를 숨겨야하며, 적어도 나를 위해 예외도 포함해야한다고 말합니다. 당신은 당신에게 그 예외의 의미가 무엇인지를보고 당신의 계급을 들려주는 사람들에게 그 의미를 나타내는 예외를 돌려 주어야합니다.

예를 들어, IllegalArgumentException와 같은 프레임 워크가 이미 해당 예외를 제공하는 경우, 새 객체를 생성하고, 발생한 일에 대한 설명이 잘 들어있는 문자열을 지정하고, ocurred 예외를 캡슐화해야합니다. 새로운 IllegalArgumentException ("인자 X가 ~ 때문에 유효하지 않습니다 ...", e); 프레임 워크에 문제에 대한 설명적인 예외가없는 경우에는 고유 한 예외 집합을 만들어야합니다. 나는 일반적으로 해당 프로젝트/패키지 (Exception 또는 RuntimeException을 확장 함)에 대한 일반 예외를 작성하고 예외를 파생시킵니다. 예를 들어, 저는 최근에 우리의 서비스와 응용 프로그램 모듈 전체에서 재사용 할 수있는 일반 저장소 프로젝트를 만들어 데이터베이스에 액세스했습니다. DB에서 액세스하는 데 사용했던 호출자를 추상화하고 싶었 기 때문에 JPA Hibernate 예외를 캡슐화하기 위해 몇 가지 예외를 작성했습니다. 여기에 코드가 없지만 다음과 비슷한 코드가 있습니다.

// implementation package 
public abstract class GenericRepository<K, E extends<K>> implements IRepository<K, E>{ 

    // constructors 

    public final void add(E entity){ 
     // some code 

     try{ 
      // code that can throw exceptions 
     } catch (EntityExistsException e) { 
      // some code 
      throw new EntityAlreadyExistsException(e); 
     } catch(RuntimeException e) { 
      // some code 
      throw new GenericRepositoryException("An unexpected exception occurred while manipulating the database", e); 
     } 
    } 

    // some other code 

} 


// exception package 
public final class EntityAlreadyExistsException extends GenericRepositoryException{ 

    public static final String GENERICMESSAGE = "The entity already exists on the table"; 

    public EntityAlreadyExistsException(Throwable cause){ 
     super(GENERICMESSAGE, cause); 
    } 

    // other constructors 

}