Java - Experimente com recursos
*1. Visão geral *
O suporte à tentativa com recursos - introduzido no Java 7 - nos permite declarar os recursos a serem usados em um bloco try com a garantia de que os recursos serão fechados quando após a execução desse bloco. Os recursos declarados devem implementar a interface AutoCloseable.
===* 2. Usando try-with-resources *
Simplificando, para ser fechado automaticamente, um recurso deve ser declarado e inicializado dentro do try, como mostrado abaixo:
try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
writer.println("Hello World");
}
===* 3. Substituindo try _ – _ catch-finally por try-with-resources *
A maneira simples e óbvia de usar a nova funcionalidade try-with-resources é substituir o bloco tradicional e detalhado try-catch-finally.
Vamos comparar os seguintes exemplos de código - primeiro é um bloco típico try-catch-finally, depois a nova abordagem, usando um bloco equivalente try-with-resources:
Scanner scanner = null;
try {
scanner = new Scanner(new File("test.txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
E aqui está a solução super sucinta usando try-with-resources:
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
===* 4. try-with-resources com vários recursos *
Vários recursos podem ser declarados perfeitamente em um bloco try-with-resources, separando-os com ponto e vírgula:
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
while (scanner.hasNext()) {
writer.print(scanner.nextLine());
}
}
===* 5. Um recurso personalizado com * AutoCloseable
Para construir um recurso personalizado que será tratado corretamente por um bloco try-with-resources, a classe deve implementar as interfaces Closeable ou AutoCloseable e substituir o método close:
public class MyResource implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("Closed MyResource");
}
}
*6. Ordem de fechamento de recursos *
Os recursos que foram definidos/adquiridos primeiro serão fechados por último; vejamos um exemplo desse comportamento:
Recurso 1:
public class AutoCloseableResourcesFirst implements AutoCloseable {
public AutoCloseableResourcesFirst() {
System.out.println("Constructor -> AutoCloseableResources_First");
}
public void doSomething() {
System.out.println("Something -> AutoCloseableResources_First");
}
@Override
public void close() throws Exception {
System.out.println("Closed AutoCloseableResources_First");
}
}
Recurso 2:
public class AutoCloseableResourcesSecond implements AutoCloseable {
public AutoCloseableResourcesSecond() {
System.out.println("Constructor -> AutoCloseableResources_Second");
}
public void doSomething() {
System.out.println("Something -> AutoCloseableResources_Second");
}
@Override
public void close() throws Exception {
System.out.println("Closed AutoCloseableResources_Second");
}
}
Código:
private void orderOfClosingResources() throws Exception {
try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst();
AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) {
af.doSomething();
as.doSomething();
}
}
Resultado:
Constructor → AutoCloseableResources_First + Constructor → AutoCloseableResources_Second + Algo → AutoCloseableResources_First + Algo → AutoCloseableResources_Second + Closed AutoCloseableResources_Second + Fechado AutoCloseableResources_Second + _Fechado
===* 7. catch & finally *
Um bloco try-with-resources* ainda pode ter os blocos catch e finally * *- que funcionarão da mesma maneira que com um bloco try tradicional.
===* 8. Conclusão *
Neste artigo, discutimos como usar try-with-resources, como substituir try, catch e finally por try-with-resources, criando recursos personalizados com AutoCloseable e a ordem na qual os recursos estão fechados.
O código-fonte completo* para o exemplo está disponível em este projeto do GitHub.