Предположим, у меня есть класс и метод
class A {
void foo() throws Exception() {
...
}
}
Теперь я хотел бы вызывать foo для каждого экземпляра, A
доставляемого потоком, например:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Вопрос: Как правильно обработать исключение? Код не компилируется на моей машине, потому что я не обрабатываю возможные исключения, которые могут быть вызваны функцией foo (). throws Exception
Из , bar
кажется, бесполезно здесь. Это почему?
java
java-8
unhandled-exception
java-stream
Бастиан
источник
источник
Ответы:
Вам нужно заключить вызов вашего метода в другой, где вы не выбрасываете проверенные исключения . Вы все еще можете бросить все, что является подклассом
RuntimeException
.Нормальная идиома обертки - это что-то вроде:
(Supertype исключением
Exception
является только используется в качестве примера, не пытаться поймать его самостоятельно)Тогда вы можете назвать его:
as.forEach(this::safeFoo)
.источник
Если все, что вам нужно, - это вызывать
foo
, и вы предпочитаете распространять исключение как есть (без переноса), вы также можете просто использоватьfor
вместо этого цикл Java (после преобразования Stream в Iterable с некоторыми хитростями ):Это, по крайней мере, то, что я делаю в своих тестах JUnit, где я не хочу испытывать трудности с упаковкой проверенных исключений (и фактически предпочитаю, чтобы мои тесты бросали развернутые исходные)
источник
Этот вопрос может быть немного старым, но потому что я думаю, что «правильный» ответ здесь - это только один из способов, который может привести к некоторым проблемам, скрытым в дальнейшем в вашем коде. Даже если есть небольшое противоречие , проверенные исключения существуют по причине.
На мой взгляд, самый изящный способ, который вы можете найти, был предложен Мишей. Агрегируйте исключения времени выполнения в потоках Java 8 , просто выполняя действия в «будущих». Таким образом, вы можете запустить все рабочие части и собрать неработающие исключения как единое целое. В противном случае вы можете собрать их все в Список и обработать позже.
Аналогичный подход исходит от Бенджи Вебера . Он предлагает создать собственный тип для сбора рабочих и не рабочих частей.
В зависимости от того, что вы действительно хотите добиться простого отображения между входными значениями и выходными значениями, возникшие исключения могут также работать для вас.
Если вам не нравится ни один из этих способов, рассмотрите возможность использования (в зависимости от исходного исключения) как минимум собственного исключения.
источник
stream.map(Streams.passException(x->mightThrowException(x))).catch(e->whatToDo(e)).collect(...)
, Он должен ожидать исключений и позволять вам обрабатывать их как фьючерсы.Я предлагаю использовать Google Guava Throwables класс
ОБНОВИТЬ:
Теперь, когда это устарело, используйте:
источник
Вы можете обернуть и развернуть исключения таким образом.
источник
Вы можете сделать одно из следующих действий:
Несколько библиотек позволяют вам сделать это легко. Пример ниже написан с использованием моей библиотеки NoException .
источник
Более читаемый способ:
Просто скройте это,
RuntimeException
чтобы пройтиforEach()
Хотя в этот момент я не буду против кого-то, если они скажут пропустить потоки и пойти с циклом for, если только:
Collection.stream()
, то есть не прямого перевода в цикл for.parallelstream()
источник