Eu tenho um bloco para escrever dados (string) usando BufferedWriter, mas o compilador continua dizendo erro: exceção não relatada IOException; deve ser capturado ou declarado para ser lançado this.dataContainer.stream().forEach( line ->writer.write(line) );
Já está BufferWrite.write()
dentro de um bloco try-catch. O erro é causado por ele aninhado dentro if-else
? Como deve ser escrito?
void saveData() throws IOException {
String filename;
Path filePath;
BufferedWriter writer;
filename = "missionImpossible9.csv";
filePath = this.dirPath.resolve(filename); //make path of this file
writer = Files.newBufferedWriter(filePath);
try {
if (condition1) {
this.dataContainer1.stream().forEach( line -> writer.write(line) );
} else {
this.dataContainer2.stream().forEach( line -> writer.write(line) );
}
writer.close();
} catch (IOException err){
err.getStackTrace();}
}
O problema é que o método
write()
deBufferedWriter
é declarado como throwIOException
, mas você está chamando-o dentro de umConsumer<?>
(the.forEach()
) que não deveria lançar nenhuma exceção verificada:A expressão
line -> writer.write(line)
é uma expressão lambda que implementa a interface funcionalConsumer
e você não pode lançar exceções verificadas (comoIOException
) dentro de um lambda.A maneira de resolver o problema é capturar o
IOException
interior do próprio lambda e relançá-lo em umRuntimeException
(que está desmarcado):Neste ponto, você não precisa
IOException
mais capturar (em qualquer caso, seIOException
ocorrer um dewrite()
você, você o receberá como umaRuntimeException
causa queIOException
.Nota: existem maneiras melhores de manter o tipo
IOException
sem que o compilador reclame, o que é chamado de Sneaky Throw. Você pode querer ler este artigo sobre isso: Artigo sobre lançamentos furtivos . De modo geral, não é sugerido silenciar uma exceção verificada como esta, mas às vezes não há outra escolha (por exemplo, quando você deseja executar código dentro de uma expressão lambda e precisa usar uma interface funcional que não lança, comoConsumer
).