Java - Experimente com recursos

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.