implementa Closeable o implementa AutoCloseable

7 minutos de lectura

avatar de usuario
malas

Estoy en el proceso de aprender Java y no puedo encontrar ninguna buena explicación en el implements Closeable y el implements AutoCloseable interfaces

Cuando implementé un interface Closeablemi Eclipse IDE creó un método public void close() throws IOException.

Puedo cerrar la transmisión usando pw.close(); sin la interfaz. Pero, no puedo entender cómo puedo implementar elclose() método usando la interfaz. Y, ¿cuál es el propósito de esta interfaz?

También me gustaría saber: ¿cómo puedo comprobar si IOstream estaba realmente cerrado?

Estaba usando el código básico a continuación

import java.io.*;

public class IOtest implements AutoCloseable {

public static void main(String[] args) throws IOException  {

    File file = new File("C:\\test.txt");
    PrintWriter pw = new PrintWriter(file);

    System.out.println("file has been created");

    pw.println("file has been created");

}

@Override
public void close() throws IOException {


}

avatar de usuario
Tomasz Nurkiewicz

AutoCloseable (introducido en Java 7) hace posible usar el prueba-con-recursos modismo:

public class MyResource implements AutoCloseable {

    public void close() throws Exception {
        System.out.println("Closing!");
    }

}

Ahora puedes decir:

try (MyResource res = new MyResource()) {
    // use resource here
}

y JVM llamará close() automáticamente para usted.

Closeable es una interfaz más antigua. Por alguna razón Para preservar la compatibilidad con versiones anteriores, los diseñadores de idiomas decidieron crear uno separado. Esto permite no sólo a todos Closeable clases (como arroyos lanzando IOException) para ser utilizado en Try-with-resources, pero también permite lanzar excepciones comprobadas más generales de close().

En caso de duda, utilice AutoCloseablelos usuarios de tu clase te lo agradecerán.

  • La razón es simple: Closeable.close() lanza IOException. Un monton de close() los métodos que podrían beneficiarse de probar con recursos lanzan otras excepciones comprobadas (p. ej. java.sql.Connection.close() asi que AutoCloseable.close() lanza Exception. Cambiando lo existente Closeable el contrato rompería todas las aplicaciones/biblioteca existentes basándose en el contrato que close() solo lanza IOException y no todas las excepciones (marcadas).

    – Mark Rotteveel

    30 de octubre de 2012 a las 14:49


  • @MarkRotteveel: +1, gracias. Corregí mi respuesta para reflejar sus sugerencias y comentarios.

    – Tomasz Nurkiewicz

    30 de octubre de 2012 a las 14:57

  • Y también: Closeable.close() se requiere que sea idempotente. AutoCloseable.close() no lo es, aunque sigue siendo muy recomendable.

    – Lucas Eder

    25/01/2014 a las 17:00

  • Además, no utilice el valor predeterminado public void close( ) throws Exception — use una excepción más específica si puede (por ejemplo, IOException)

    – Gerardo

    15 de noviembre de 2014 a las 20:23

  • Closeable no es garantizar idempotencia. Eso requiere idempotencia en la implementación de un usuario de la close() método. Y si IOException es más específico/apropiado depende del caso de uso.

    – xdhmoore

    15 de julio de 2015 a las 22:33


avatar de usuario
JB Nizet

Closeable extiende AutoCloseabley está específicamente dedicado a flujos IO: lanza IOException en vez de Exceptiony es idempotente, mientras que AutoCloseable no proporciona esta garantía.

Todo esto se explica en el javadoc de ambas interfaces.

Implementar AutoCloseable (o Closeable) permite utilizar una clase como recurso del prueba-con-recursos constructo introducido en Java 7, que permite cerrar dichos recursos automáticamente al final de un bloque, sin tener que agregar un finally bloque que cierra el recurso explícitamente.

Su clase no representa un recurso que se pueda cerrar, y no tiene absolutamente ningún sentido implementar esta interfaz: una IOTest no se puede cerrar Ni siquiera debería ser posible instanciarlo, ya que no tiene ningún método de instancia. Recuerde que implementar una interfaz significa que hay un es un relación entre la clase y la interfaz. No tienes esa relación aquí.

  • solo implementa Cerrable para clases relacionadas con flujos, y Cierre automático para otros que requieren la función de cierre automático.

    – lospejos

    13 de julio de 2016 a las 15:13

avatar de usuario
kai

Me parece que no estás muy familiarizado con las interfaces. En el código que ha publicado, no necesita implementar AutoCloseable.

Solo tienes que (o deberías) implementar Closeable o AutoCloseable si está a punto de implementar su propio PrintWriterque maneja archivos o cualquier otro recurso que deba cerrarse.

En su implementación, es suficiente llamar pw.close(). Deberías hacer esto en un bloque finalmente:

PrintWriter pw = null;
try {
   File file = new File("C:\\test.txt");
   pw = new PrintWriter(file);
} catch (IOException e) {
   System.out.println("bad things happen");
} finally {
   if (pw != null) {
      try {
         pw.close();
      } catch (IOException e) {
      }
   }
}

El código anterior está relacionado con Java 6. En Java 7 esto se puede hacer de manera más elegante (ver esta respuesta).

  • ¿Por qué sólo con un PrintWriter? Especialmente AutoClosable los objetos se pueden utilizar en muchas más circunstancias que simplemente PrintWriters…

    – glglgl

    26 de enero de 2015 a las 14:53

  • Tienes toda la razón. la pregunta era sobre PrintWriter así que lo mencioné para ser más específico.

    – Kai

    26 de enero de 2015 a las 19:48

  • ¿Por qué describir la situación de Java 6 en el contexto de AutoCloseable? Mejor mostrar un try-with-resources en cambio …

    – ᴠɪɴᴄᴇɴᴛ

    1 de diciembre de 2017 a las 14:09

avatar de usuario
Lova Chittumuri

Aquí está el pequeño ejemplo.

public class TryWithResource {

    public static void main(String[] args) {
        try (TestMe r = new TestMe()) {
            r.generalTest();
        } catch(Exception e) {
            System.out.println("From Exception Block");
        } finally {
            System.out.println("From Final Block");
        }
    }
}



public class TestMe implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println(" From Close -  AutoCloseable  ");
    }

    public void generalTest() {
        System.out.println(" GeneralTest ");
    }
}

Aquí está la salida:

GeneralTest 
From Close -  AutoCloseable  
From Final Block

avatar de usuario
Arvind Katte

Recientemente he leído un libro de la Guía del programador de Java SE 8 ii.

Encontré algo sobre la diferencia entre AutoCloseable contra Closeable.

los AutoCloseable interfaz se introdujo en Java 7. Antes de eso, existía otra interfaz llamada Closeable. Era similar a lo que querían los diseñadores del lenguaje, con las siguientes excepciones:

  • Closeable restringe el tipo de excepción lanzada a IOException.
  • Closeable requiere que las implementaciones sean idempotentes.

Los diseñadores del lenguaje enfatizan la compatibilidad con versiones anteriores. Dado que cambiar la interfaz existente no era deseable, crearon una nueva llamada AutoCloseable. Esta nueva interfaz es menos estricta que Closeable. Ya que Closeable cumple con los requisitos para
AutoCloseablecomenzó a implementar AutoCloseable cuando se presentó este último.

  • En lugar de decir que “Esta nueva interfaz es menos estricta que Closeable“, sugeriría decir “Esta nueva interfaz se puede usar en contextos más generales, donde la excepción lanzada durante el cierre no es necesariamente una IOException”. En el universo de Java, ser “menos estricto” tiene una vibra negativa al respecto.

    – manantial

    8 de septiembre de 2019 a las 4:47


avatar de usuario
ItamarG3

los try-with-resources Declaración.

los try-with-resources statement es un try declaración que declara uno o más recursos. A resource es un objeto que debe cerrarse después de que el programa termine con él. los try-with-resources statement asegura que cada recurso se cierre al final de la declaración. Cualquier objeto que implemente java.lang.AutoCloseableque incluye todos los objetos que implementan java.io.Closeablese puede utilizar como un recurso.

El siguiente ejemplo lee la primera línea de un archivo. Utiliza una instancia de BufferedReader para leer los datos del archivo. BufferedReader es un recurso que debe cerrarse después de que el programa termine con él:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

En este ejemplo, el recurso declarado en la sentencia try-with-resources es un BufferedReader. La declaración de declaración aparece entre paréntesis inmediatamente después de la palabra clave try. La clase BufferedReaderen Java SE 7 y posterior, implementa la interfaz java.lang.AutoCloseable. Porque el BufferedReader se declara una instancia en una declaración try-with-resource, se cerrará independientemente de si la declaración try se completa de manera normal o abrupta (como resultado del método BufferedReader.readLine lanzando un IOException).

Antes de Java SE 7, puede usar un finally block para asegurarse de que un recurso se cierre independientemente de si la instrucción try se completa de forma normal o abrupta. El siguiente ejemplo utiliza un finally bloque en lugar de un try-with-resources declaración:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }

}

Por favor consulte los documentos.

  • En lugar de decir que “Esta nueva interfaz es menos estricta que Closeable“, sugeriría decir “Esta nueva interfaz se puede usar en contextos más generales, donde la excepción lanzada durante el cierre no es necesariamente una IOException”. En el universo de Java, ser “menos estricto” tiene una vibra negativa al respecto.

    – manantial

    8 de septiembre de 2019 a las 4:47


¿Ha sido útil esta solución?