Suponha que eu tenha uma classe e um método
class A {
void foo() throws Exception() {
...
}
}
Agora eu gostaria de chamar foo para cada instância A
entregue por um fluxo como:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Pergunta: Como manejo adequadamente a exceção? O código não é compilado na minha máquina porque eu não manejo as possíveis exceções que podem ser lançadas por foo (). O throws Exception
de bar
parece ser inútil aqui. Por que é que?
java
java-8
unhandled-exception
java-stream
Bastian
fonte
fonte
Respostas:
Você precisa agrupar sua chamada de método em outra, onde você não lança exceções verificadas . Você ainda pode jogar qualquer coisa que seja uma subclasse de
RuntimeException
.Um idioma de agrupamento normal é algo como:
(A exceção Supertype
Exception
é usada apenas como exemplo, nunca tente capturá-la)Depois, você pode chamá-lo com:
as.forEach(this::safeFoo)
.fonte
Se tudo o que você deseja é chamar
foo
e preferir propagar a exceção como está (sem quebra), você também pode usar ofor
loop do Java (depois de transformar o Stream em um Iterable com alguns truques ):Isso é, pelo menos, o que faço nos meus testes JUnit, onde não quero enfrentar o problema de agrupar minhas exceções verificadas (e de fato preferir que meus testes joguem os originais não desembrulhados)
fonte
Essa pergunta pode ser um pouco antiga, mas porque acho que a resposta "certa" aqui é apenas uma maneira de levar a alguns problemas ocultos, problemas mais adiante no seu código. Mesmo se houver um pouco de controvérsia , existem exceções verificadas por um motivo.
A maneira mais elegante, na minha opinião, você pode encontrar foi dada por Misha aqui. Exceções de tempo de execução agregadas nos fluxos do Java 8 , apenas executando as ações em "futuros". Assim, você pode executar todas as peças de trabalho e coletar exceções que não funcionam como uma única. Caso contrário, você poderá coletá-los todos em uma Lista e processá-los posteriormente.
Uma abordagem semelhante vem de Benji Weber . Ele sugere criar um tipo próprio para coletar peças de trabalho e não peças de trabalho.
Dependendo do que você realmente deseja obter um mapeamento simples entre os valores de entrada e os valores de saída, as exceções também podem funcionar para você.
Se você não gostar de nenhuma dessas maneiras, considere usar (dependendo da Exceção original) pelo menos uma exceção.
fonte
stream.map(Streams.passException(x->mightThrowException(x))).catch(e->whatToDo(e)).collect(...)
. Deve esperar exceções e permitir que você lide com elas como os futuros.Sugiro usar a classe Google Guava Throwables
ATUALIZAR:
Agora que está obsoleto, use:
fonte
Você pode quebrar e desembrulhar exceções dessa maneira.
fonte
Você pode querer fazer um dos seguintes:
Várias bibliotecas permitem fazer isso facilmente. O exemplo abaixo é escrito usando minha biblioteca NoException .
fonte
Maneira mais legível:
Apenas esconda-o
RuntimeException
para conseguir passarforEach()
Embora neste momento eu não me oponha a alguém se ele disser pular os fluxos e seguir com um loop for, a menos que:
Collection.stream()
, ou seja, não é uma tradução direta para um loop for.parallelstream()
fonte