2010-02-05 4 views
25

java.lang.Iterator 인터페이스에는 hasNext, nextremove의 세 가지 메소드가 있습니다. 읽기 전용 이터레이터를 구현하려면 hasNextnext 중 2 개를 구현해야합니다.java.lang.Iterator 구현시 예외 사항 수행

제 문제는 이러한 메서드는 예외를 선언하지 않는다는 것입니다. 따라서 반복 프로세스 내의 코드가 예외를 선언하면 반복 코드를 try/catch 블록으로 묶어야합니다.

내 현재 정책은 RuntimeException에 포함 된 예외를 다시 제기했습니다. 그러나 검사 된 예외가 손실되고 클라이언트 코드가 더 이상 해당 예외를 명시 적으로 catch 할 수 없기 때문에 문제가 발생합니다.

Iterator 클래스에서이 제한을 해결하려면 어떻게해야합니까? 여기

명확성에 대한 샘플 코드 :

class MyIterator implements Iterator 
{ 
    @Override 
    public boolean hasNext() 
    { 
     try 
     { 
      return implementation.testForNext(); 
     } 
     catch (SomethingBadException e) 
     { 
      throw new RuntimeException(e); 
     } 
    } 

    @Override 
    public boolean next() 
    { 
     try 
     { 
      return implementation.getNext(); 
     } 

     catch (SomethingBadException e) 
     { 
      throw new RuntimeException(e); 
     } 
    } 

    ... 
} 

답변

9

종종 Iterator를 많이 구현했으며 때로는 with-check-exception iterator (ResultSet은 개념적으로 레코드 반복자, InputStream는 개념적으로 byte iterator) 등을 구현했습니다. 매우 유용하고 편리합니다 (많은 것을 위해 파이프 & 필터 아키텍처를 구현할 수 있습니다).

예외를 선언하는 경우을 선언 한 다음 새로운 유형의 반복자 (ExceptionIterator, Runnable 및 Callable과 같음)를 선언하십시오. 코드 또는 코드를 사용할 수 있지만 외부 구성 요소 (Java 클래스 라이브러리 또는 3D 파티 라이브러리)로 구성 할 수는 없습니다.

슈퍼 표준 인터페이스 (반복자와 같은)을 사용하여 어디에서나 사용하려면 Iterator를 사용하십시오. 예외가 처리를 중지하기위한 조건이되거나 처리에 많은 신경을 쓰지 않는 경우 예외를 사용하십시오.

런타임 예외는 그리 심각하지 않습니다. 예제로. Hibernate는 프록시를 구현하기 위해 그것들을 사용합니다. DB 예외를 제외하고 List를 구현할 때이를 선언 할 수는 없습니다.

+1

UI 클라이언트 코드를 제어 할 수없는 또 다른 옵션은 getter 또는 무언가가 액세스 할 수있는 어딘가에 예외를 등록하거나 콜백 인터페이스 또는 사용자가 제어하는 ​​대상을 등록하고 어디에서나 오류를 표시 할 수있는 반복기를 만듭니다. 이것이 유용하다면, 단순히 런타임 예외 처리기 반복자를 래핑하고 속성 또는 콜백 인터페이스로 리디렉션하는 모든 위장 가능한 예외를 잡는 "CatcherIterator"를 만들 수 있습니다. – helios

1

구현이 반복자 인터페이스가 필요로하는 특성, 왜 당신이 그것을 사용하고 싶어이없는 경우?

RuntimeException (문제가 있음) 이외의 해결책은 없습니다.

11

예를 들어 SomethingBadRuntimeException과 같이 일반 런타임이 아닌 사용자 정의 런타임 예외로 예외를 다시 게시해야합니다. 또한 exception tunneling을 사용해보세요.

그리고 저는 클라이언트가 예외를 처리하도록 강요하는 것은 나쁜 습관임을 확신합니다. 코드 나 강제로 코드를 실행 시간 예외로 감싸거나 호출 대신 처리하지만 강제적으로 처리하지는 않습니다. 내 정책은 가능한 한 많이 검사 된 예외를 사용하지 않는 것입니다. 을 Closable.close()에 올려보세요 : 유용하거나 편리합니까? 당시의 사례는 매우 드물지만 전 세계의 모든 Java 개발자가 처리해야합니다. 가장 자주 삼켜 지거나 잘 기록됩니다. 이것이 code size에 얼마나 많이 추가되는지 상상해보십시오! 자신의 어두운면에서 체크 된 예외에 대한 몇 가지 게시물있다 : 체크 된 예외가 구출에 관해서

  1. "Does Java need Checked Exceptions?" by Bruce Eckel
  2. The Trouble with Checked Exceptions A Conversation with Anders Hejlsberg, by Bill Venners with Bruce Eckel
  3. Java Design Flaws, C2 wiki

는 경우가 있습니다. 그러나 제 의견으로는 드물기는하지만 보통 특정 모듈을 구현하는 데 관심이 있습니다. 그리고 그들은 많은 이익을주지 않습니다. 자바 체크 된 예외를 좋아하는 사람으로

3

, 나는 문제 (자바 설계 결함 만약에 당신이) 표준 라이브러리가 next 방법은 확인이 끝난 예외를 throw하는 일반 반복자 유형을 지원하지 않는 것이라고 생각합니다.

코드베이스 Sesame에는 Iterable이라는 Iterator 변형 클래스가 있습니다. 다음과 같이 서명은 다음과 같습니다

 
Interface Iteration<E,X extends Exception> 

Type Parameters: 
    E - Object type of objects contained in the iteration. 
    X - Exception type that is thrown when a problem occurs during iteration. 

이 특정 서브 클래스가 사용되는 참깨의 제한된 환경에서 작동하는 것 같다 예외 유형 매개 변수를 "해결". 그러나 (물론) 표준 컬렉션 유형, Java 5의 새로운 for 루프 구문 등과 통합되지는 않습니다.

2

hasNext가 실제로 예외를 throw해서는 안됩니다. 계속 진행하고 그 기준으로 부울 값을 반환하는 것이 확인되어야합니다 (로거와 함께 기본 예외가 기록됩니다). 다음에 실패하면 RuntimeException을 던질 것입니다 (그리고 로거로 검사 된 예외를 기록하십시오). 다음 테스트는 정상적인 조건에서는 실패하지 않아야하며 테스트가 실패하면 다음에 호출해서는 안됩니다 (따라서 런타임 예외). 무슨 일이 있어도

1

이 트릭 :-)를 않지만, 이리. 추가 인터페이스 또는 클래스 ExceptionHandler은 Iterator를 구현하는 클래스 내에서 구성 될 수 있으며 클라이언트가 원하는대로 예외를 처리하도록 구현할 수 있습니다.

public interface ExceptionHandler { 
    // Log, or rethrow, or ignore... 
    public Object handleException(Exception e); 
} 

구현 클래스는 다음과 같이 할 수 있습니다 : 파일에서 읽어 반복자를 들어

public class ExceptionRethrower implements ExceptionHandler { 
    @Override 
    public Object handleException(Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

public class ExceptionPrinter implements ExceptionHandler { 
    @Override 
    public Object handleException(Exception e) { 
     System.err.println(e); 
     return e; 
    } 
} 

를 코드는 다음과 같이 보일 수 있습니다

public class MyReaderIterator implements Iterator<String> { 
    private final BufferedReader reader; 
    private final ExceptionHandler exceptionHandler; 
    public MyReaderIterator(BufferedReader r, ExceptionHandler h) { 
     reader = r; 
     exceptionHandler = h; 
    } 
    @Override 
    public String next() { 
     try { 
      return reader.readLine(); 
     } catch (IOException ioe) { 
      Object o = exceptionHandler.handleException(ioe); 
      // could do whatever else with o 
      return null; 
     } 
    } 
    // also need to implement hasNext and remove, of course 
} 

사람들이 어떻게 생각하십니까 ? 이 간접적 인 수준의 가치가 있거나 계층화 된 위반이며 너무 단순합니다. 인터페이스의 이름은 아마도 적절하지 않을 수 있습니다 (ExceptionProcessor 또는 ExceptionInterceptor는 상호 작용할 수 있기 때문에 예외를 완전히 처리 할 수 ​​없으므로 구성되어있는 클래스에서 처리해야합니다).

나는이 모든 것이 Iterator.next()가 예외를 throw하도록 선언되지 않았기 때문에 발전기와 파이썬의 예외 모델에 대한 소나무가되게한다는 것에 동의한다.

0

나는 usally

@Override 
void remove() { 
    throws new UnsupportedOperationException("remove method not implemented"); 
} 

메모를 사용 UnsupportedOperationException를 사용하면 properbly

for (IterElem e : iterable) 
    e.action(); 

처럼 뭔가를 목표로하고 있기 때문에 RuntimeException을

당신이

1

잘 당신이 만약 정말로있을 것입니다 런타임 예외를 사용하지 않으려면를 사용할 수 있습니다.. Iterator 정의에 던져진 것으로 선언되었으므로 무시 된 next() 메서드에서이 메서드를 사용할 수 있습니다.이 코드와 코드를 컴파일 해 보았습니다. 그러나 귀하의 경우에 유효한 의미 적으로인지 여부를 고려해야합니다. 내 마음에

+0

나는 iterator 에러를 던지기위한 가장 좋은 예외라고 생각한다. – smac89

+0

'NoSuchElementException'은'RuntimeException'이다. 'RuntimeException'에 대한 커스텀 확장을 만들 수도 있습니다. – boumbh

-1

가, 반복자는 으로 반복에 의미, 그들은 컴퓨팅next() 방법에 throws의 따라서 부재로 의미하지 않는다.

인터페이스를 사용하여 설계되지 않은 작업을 수행하는 방법을 묻습니다. Iterator 당신이 할 수있는 사용하는 경우, 다음

public Element safeNext() throws YourCheckedException { 
    ... 
} 

@Override 
public Element next() { 
    try { 
     return safeNext(); 
    } catch (YourException e) { 
     throw new YourRuntimeException("Could not fetch the next element", e); 
    } 
} 

다음 Iterator가 (나쁜 가정이 일반적이다) 직접 사용하기위한 경우

하지만,이 같은 공공 safeNext() 방법을 정의 할 수 있습니다 safeNext()을 사용하고 체크 된 예외를 처리하도록 선택하거나 어떤 이터레이터와 마찬가지로 next()을 사용하십시오.

즉, 반복자 인터페이스의 편리함 (Iterable 개체가 safeNext() 메서드를 사용할 것으로 예상 할 수 없음)과 체크 예외가 발생하는 것을 모두 알 수 없습니다.

관련 문제