Java try-with-resources (com exemplos)

Neste tutorial, aprenderemos sobre a instrução try-with-resources para fechar recursos automaticamente.

A try-with-resourcesinstrução fecha automaticamente todos os recursos no final da instrução. Um recurso é um objeto a ser encerrado no final do programa.

Sua sintaxe é:

 try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block ) 

Como visto na sintaxe acima, declaramos a try-with-resourcesinstrução por,

  1. declarar e instanciar o recurso dentro da trycláusula.
  2. especificando e tratando todas as exceções que podem ser lançadas ao fechar o recurso.

Nota: A instrução try-with-resources fecha todos os recursos que implementam a interface AutoCloseable.

Tomemos um exemplo que implemente a try-with-resourcesdeclaração.

Exemplo 1: try-with-resources

 import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) ) 

Saída se o arquivo test.txt não for encontrado.

 IOException em try-with-resources block => test.txt (nenhum arquivo ou diretório) 

Saída se o arquivo test.txt for encontrado.

 Entrando no bloco try-with-resources Line => test line 

Neste exemplo, usamos uma instância de BufferedReader para ler os dados do test.txtarquivo.

Declarar e instanciar o BufferedReader dentro da try-with-resourcesinstrução garante que sua instância seja fechada, independentemente de a tryinstrução ser concluída normalmente ou gerar uma exceção.

Se ocorrer uma exceção, ela pode ser tratada usando os blocos de tratamento de exceção ou a palavra-chave throws.

Exceções suprimidas

No exemplo acima, exceções podem ser lançadas da try-with-resourcesinstrução quando:

  • O arquivo test.txtnão foi encontrado.
  • Fechando o BufferedReaderobjeto.

Uma exceção também pode ser lançada do trybloco, pois a leitura de um arquivo pode falhar por vários motivos a qualquer momento.

Se exceções forem lançadas do trybloco e da try-with-resourcesinstrução, a exceção do trybloco será lançada e a exceção da try-with-resourcesinstrução será suprimida.

Recuperando exceções suprimidas

No Java 7 e posterior, as exceções suprimidas podem ser recuperadas chamando o Throwable.getSuppressed()método da exceção lançada pelo trybloco.

Este método retorna uma matriz de todas as exceções suprimidas. Obtemos as exceções suprimidas no catchbloco.

 catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) ) 

Vantagens de usar try-with-resources

Aqui estão as vantagens de usar try-with-resources:

1. por fim, não é necessário bloquear para fechar o recurso

Antes do Java 7 introduzir esse recurso, tínhamos que usar o finallybloco para garantir que o recurso fosse fechado para evitar vazamentos de recursos.

Este é um programa semelhante ao Exemplo 1 . No entanto, neste programa, usamos o bloco final para fechar os recursos.

Exemplo 2: Fechar o recurso usando finally block

 import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) ) 

Resultado

 Inserindo o bloco try Line => linha do arquivo test.txt Entrando no bloco 

Como podemos ver no exemplo acima, o uso de finallybloco para limpar recursos torna o código mais complexo.

Observe o try… catchbloco no finallybloco também? Isso ocorre porque um IOExceptiontambém pode ocorrer ao fechar a BufferedReaderinstância dentro desse finallybloco, portanto, ele também é capturado e tratado.

A try-with-resourcesinstrução faz o gerenciamento automático de recursos . Não precisamos fechar explicitamente os recursos, pois a JVM os fecha automaticamente. Isso torna o código mais legível e fácil de escrever.

2. tentar com recursos com vários recursos

Podemos declarar mais de um recurso na try-with-resourcesinstrução, separando-os com um ponto e vírgula;

Exemplo 3: experimente com vários recursos

 import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) ) 

Se este programa for executado sem gerar nenhuma exceção, o Scannerobjeto lê uma linha do testRead.txtarquivo e a grava em um novo testWrite.txtarquivo.

Quando várias declarações são feitas, a try-with-resourcesinstrução fecha esses recursos na ordem inversa. Neste exemplo, o PrintWriterobjeto é fechado primeiro e, em seguida, o Scannerobjeto é fechado.

Aprimoramento do Java 9 try-with-resources

No Java 7, há uma restrição à try-with-resourcesinstrução. O recurso precisa ser declarado localmente em seu bloco.

 try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code ) 

Se declarássemos o recurso fora do bloco em Java 7, ele teria gerado uma mensagem de erro.

 Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code ) 

Para lidar com esse erro, o Java 9 aprimorou a try-with-resourcesinstrução para que a referência do recurso possa ser usada mesmo se não for declarada localmente. O código acima agora será executado sem nenhum erro de compilação.

Artigos interessantes...