Estou esperando que o leitor em buffer e o leitor de arquivos fechem e os recursos sejam liberados se a exceção for lançada.
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
{
return read(br);
}
}
No entanto, é necessário ter uma catch
cláusula para o fechamento bem-sucedido?
EDITAR:
Essencialmente, o código acima em Java 7 é equivalente ao código abaixo para Java 6:
public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(filePath));
return read(br);
}
catch (Exception ex)
{
throw ex;
}
finally
{
try
{
if (br != null) br.close();
}
catch(Exception ex)
{
}
}
return null;
}
java-7
try-with-resources
guepardo
fonte
fonte
catch
de seu exemplo para Java 6. Ou sejacatch (Exception ex) { throw ex; }
- ele está apenas relançando a exceção, não está fazendo nada, pode ser facilmente removido sem nenhum dano. Ou eu estou esquecendo de alguma coisa?Respostas:
Está correto e não há exigência de
catch
cláusula. Oracle java 7 doc diz que o recurso será fechado independentemente de uma exceção ser realmente lançada ou não.Você deve usar uma
catch
cláusula apenas se quiser reagir à exceção. Acatch
cláusula será executada após o encerramento do recurso.Aqui está um snippet do tutorial da Oracle :
EDITAR
Em relação à nova questão editada:
O código em Java 6 executa
catch
ofinally
bloco e depois o bloco. Isso faz com que os recursos ainda sejam potencialmente abertos nocatch
bloco.Na sintaxe Java 7, os recursos são fechados antes do
catch
bloco, portanto, os recursos já estão fechados durante acatch
execução do bloco. Isso está documentado no link acima:fonte
Seu uso de try-with-resources funcionará bem neste caso específico, mas não é totalmente correto em geral. Você não deve encadear recursos como esse, porque pode levar a surpresas desagradáveis. Suponha que você tenha um tamanho de buffer variável:
Suponha que algo deu errado e você acabou
sz
sendo negativo. Neste caso, seu recurso de arquivo (criado vianew FileReader(filePath)
) NÃO será fechado.Para evitar esse problema, você deve especificar cada recurso separadamente, como este:
Neste caso, mesmo se a inicialização de
br
falhafile
ainda for fechada. Você pode encontrar mais detalhes aqui e aqui .fonte
new FileReader(filePath))
não fechava caso umIllegalArgumentException
fosse lançado quando sz fosse negativo. O try-with-resources não fecha todos osAutoClosable
recursos, independentemente de quaisquer exceções lançadas?.close()
as variáveis que foram declaradas no inicializador try-with-resources. É por isso que separá-lo em duas declarações neste exemplo resolve o problema.sz < 0
faz com que o construtor lance uma exceção irá de fato causar o vazamento do recurso.