programing

Java 8: 스트림에 예외를 두는 방법을 사용하는 방법은 무엇입니까?

firstcheck 2022. 7. 5. 00:00
반응형

Java 8: 스트림에 예외를 두는 방법을 사용하는 방법은 무엇입니까?

클래스 및 메서드가 있다고 가정합니다.

class A {
  void foo() throws Exception() {
    ...
  }
}

이제 나는 각각의 인스턴스에 대해 foo를 호출하고 싶다.A다음과 같은 흐름에 의해 전달됩니다.

void bar() throws Exception {
  Stream<A> as = ...
  as.forEach(a -> a.foo());
}

질문:.예외를 적절하게 처리하려면 어떻게 해야 합니까?foo()에 의해 발생할 수 있는 예외를 처리하지 않기 때문에 코드가 머신에서 컴파일되지 않습니다.throws Exceptionbar여기선 쓸모없는 것 같아왜 그런 것일까요?

메서드 호출을 다른 메서드로 래핑해야 합니다.여기서 체크된 예외를 발생시키지 않습니다.서브클래스의 서브클래스는 아직 던질 수 있습니다.RuntimeException.

일반적인 포장용어는 다음과 같습니다.

private void safeFoo(final A a) {
    try {
        a.foo();
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

(슈퍼타입 예외)Exception예시로만 사용되므로 직접 잡으려고 하지 마십시오.)

다음으로 호출할 수 있습니다.as.forEach(this::safeFoo).

만약 당신이 원하는 것은foo(랩핑 없이) 예외를 그대로 전파하는 것을 선호합니다.또한 Java의for대신 루프( 가지 속임수로 스트림을 반복 가능한 것으로 바꾼 후):

for (A a : (Iterable<A>) as::iterator) {
   a.foo();
}

적어도 JUnit 테스트에서는 체크한 예외를 포장하는 번거로움을 겪고 싶지 않습니다(실제로 테스트에서는 포장되지 않은 원래 것을 버리는 것이 좋습니다).

이 질문은 다소 오래된 것일 수 있지만, 여기서의 "올바른" 답변은 코드 뒤에 숨겨진 문제로 이어질 수 있는 한 가지 방법이라고 생각하기 때문입니다.약간의 논란이 있더라도 체크된 예외는 이유가 있습니다.

내 생각에 가장 우아한 방법은 "미래"에서 액션을 수행하는 것만으로 Java 8 스트림의 Aggregate 런타임 예외를 Misha에 의해 제시했다는 것이다.따라서 모든 작업 부품을 실행하고 작동하지 않는 예외를 하나로 수집할 수 있습니다.그렇지 않으면 모두 목록에 수집하여 나중에 처리할 수 있습니다.

Benji Weber도 비슷한 접근방식을 취하고 있습니다.그는 작업 부품이 아닌 작업 부품을 수집할 수 있는 고유한 유형을 만들 것을 제안합니다.

입력값과 발생된 출력값 간의 간단한 매핑을 원하는 항목에 따라 예외가 적용될 수도 있습니다.

이러한 방법이 마음에 들지 않으면 (원래 예외에 따라) 최소한 자체 예외를 사용해 보십시오.

다음 중 하나를 수행할 수 있습니다.

  • 선택된 예외 전파,
  • 랩하여 체크되지 않은 예외를 전파합니다.또는
  • 예외를 포착하여 전파를 정지합니다.

여러 라이브러리에서 쉽게 실행할 수 있습니다.다음 예시는 No Exception 라이브러리를 사용하여 작성된 것입니다.

// Propagate checked exception
as.forEach(Exceptions.sneak().consumer(A::foo));

// Wrap and propagate unchecked exception
as.forEach(Exceptions.wrap().consumer(A::foo));
as.forEach(Exceptions.wrap(MyUncheckedException::new).consumer(A::foo));

// Catch the exception and stop propagation (using logging handler for example)
as.forEach(Exceptions.log().consumer(Exceptions.sneak().consumer(A::foo)));

Google Guava Throwables 클래스를 사용하는 것이 좋습니다.

전파(던질 수 있음)

Runtime 인스턴스인 경우 그대로 던질 수 있는 전파예외 또는 오류, 또는 마지막 수단으로 런타임으로 래핑합니다.예외 후 전파됩니다.**

void bar() {
    Stream<A> as = ...
    as.forEach(a -> {
        try {
            a.foo()
        } catch(Exception e) {
            throw Throwables.propagate(e);
        }
    });
}

갱신:

더 이상 사용하지 않습니다.

void bar() {
    Stream<A> as = ...
    as.forEach(a -> {
        try {
            a.foo()
        } catch(Exception e) {
            Throwables.throwIfUnchecked(e);
            throw new RuntimeException(e);
        }
    });
}

예외는 이 방법으로 래핑 및 래핑 해제할 수 있습니다.

class A {
    void foo() throws Exception {
        throw new Exception();
    }
};

interface Task {
    void run() throws Exception;
}

static class TaskException extends RuntimeException {
    private static final long serialVersionUID = 1L;
    public TaskException(Exception e) {
        super(e);
    }
}

void bar() throws Exception {
      Stream<A> as = Stream.generate(()->new A());
      try {
        as.forEach(a -> wrapException(() -> a.foo())); // or a::foo instead of () -> a.foo()
    } catch (TaskException e) {
        throw (Exception)e.getCause();
    }
}

static void wrapException(Task task) {
    try {
        task.run();
    } catch (Exception e) {
        throw new TaskException(e);
    }
}

읽기 쉬운 방법:

class A {
  void foo() throws MyException() {
    ...
  }
}

냥 a a 에 숨겨라.RuntimeExceptionforEach()

  void bar() throws MyException {
      Stream<A> as = ...
      try {
          as.forEach(a -> {
              try {
                  a.foo();
              } catch(MyException e) {
                  throw new RuntimeException(e);
              }
          });
      } catch(RuntimeException e) {
          throw (MyException) e.getCause();
      }
  }

이 시점에서는 스트림을 건너뛰고 for loop을 실행한다고 해도 상대하지 않습니다.단, 다음과 같은 경우는 제외합니다.

  • 게 스트림을 만드는 Collection.stream() loop로
  • 사용하려고 parallelstream()

언급URL : https://stackoverflow.com/questions/23548589/java-8-how-do-i-work-with-exception-throwing-methods-in-streams

반응형