Je suis en train d'apprendre Java et je ne trouve aucune bonne explication sur les interfaces implements Closeable
et implements AutoCloseable
.
Lorsque j'ai implémenté un interface Closeable
, mon Eclipse IDE a créé une méthode public void close() throws IOException
.
Je peux fermer le flux à l'aide de pw.close();
sans l'interface. Mais je ne comprends pas comment implémenter la méthode close()
à l'aide de l'interface. Et quel est le but de cette interface?
Aussi, j'aimerais savoir: comment puis-je vérifier si IOstream
était vraiment fermé?
J'utilisais le code de base ci-dessous
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 {
}
Il me semble que vous n'êtes pas très familier avec les interfaces. Dans le code que vous avez posté, vous n'avez pas besoin d'implémenter AutoCloseable
.
Vous devrez seulement (ou devriez) implémenter Closeable
ou AutoCloseable
si vous êtes sur le point d'implémenter une propre PrintWriter
qui gère les fichiers ou toute autre ressource devant être fermée.
Dans votre implémentation, il suffit d'appeler pw.close()
. Vous devriez le faire dans un bloc enfin:
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) {
}
}
}
Le code ci-dessus est lié à Java 6. En Java 7, cela peut être plus élégant (voir cette réponse ).
AutoCloseable
(introduit dans Java 7) permet d'utiliser l'idiome try-with-resources:
public class MyResource implements AutoCloseable {
public void close() throws Exception {
System.out.println("Closing!");
}
}
maintenant vous pouvez dire:
try(MyResource res = new MyResource()) {
//use res here
}
et JVM appellera close()
automatiquement pour vous. Closeable
est une ancienne interface. Pour certaines raisons Pour préserver la compatibilité ascendante, les concepteurs de langage ont décidé de créer un langage distinct. De cette façon, non seulement toutes les classes Closeable
(comme les flux renvoyant IOException
) peuvent être utilisées dans les ressources d’essai, mais aussi celles qui souhaitent générer une exception vérifiée plus générale à partir de close()
.
En cas de doute, utilisez AutoCloseable
, les utilisateurs de votre classe en seront reconnaissants.
Closeable
étend AutoCloseable
et est spécifiquement dédié aux flux IO: il génère une exception IOException au lieu d’Exception et est idempotent, alors qu’AutoClosable ne fournit pas cette garantie.
Tout cela est expliqué dans le javadoc des deux interfaces.
L'implémentation d'AutoCloseable (ou de Closeable) permet à une classe d'être utilisée comme ressource de la construction try-with-resources introduite dans Java 7, ce qui permet de fermer automatiquement ces ressources à la fin d'un bloc, sans avoir à ajouter un bloc final qui ferme la ressource explicitement.
Votre classe ne représente pas une ressource pouvant être fermée, et il est absolument inutile de mettre en œuvre cette interface: un IOTest ne peut pas être fermé. Il ne devrait même pas être possible de l'instancier, car il n'a pas de méthode d'instance. N'oubliez pas que l'implémentation d'une interface signifie qu'il existe une relation est-a / entre la classe et l'interface. Vous n'avez pas une telle relation ici.
Voici le petit exemple
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 ");
}
}
Voici la sortie:
GeneralTest
From Close - AutoCloseable
From Final Block
La déclaration try-with-resources
.
Le try-with-resources statement
est une instruction try
qui déclare une ou plusieurs ressources. resource
est un objet qui doit être fermé une fois que le programme est terminé. Le try-with-resources statement
garantit que chaque ressource est fermée à la fin de l'instruction. Tout objet implémentant Java.lang.AutoCloseable
, qui inclut tous les objets implémentant Java.io.Closeable
, peut être utilisé comme ressource.
L'exemple suivant lit la première ligne d'un fichier. Il utilise une instance de BufferedReader
pour lire les données du fichier. BufferedReader
est une ressource qui doit être fermée une fois le programme terminé:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Dans cet exemple, la ressource déclarée dans l'instruction try-with-resources est un BufferedReader. L'instruction de déclaration apparaît entre parenthèses immédiatement après le mot clé try. La classe BufferedReader
, dans Java SE 7 et versions ultérieures, implémente l'interface Java.lang.AutoCloseable
. Etant donné que l'instance BufferedReader
est déclarée dans une instruction try-with-resource, elle sera fermée, que l'instruction try se termine normalement ou de manière abrupte (à la suite de la méthode BufferedReader.readLine
qui a lancé une IOException
).
Avant Java SE 7, vous pouvez utiliser un bloc finally
pour vous assurer qu'une ressource est fermée, que l'instruction try se termine normalement ou de manière abrupte. L'exemple suivant utilise un bloc finally
au lieu d'une instruction try-with-resources
:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
S'il vous plaît reportez-vous à la documentation .
Récemment, j'ai lu un livre ii du Guide du programmeur Java SE 8.
J'ai trouvé quelque chose à propos de la différence entre AutoCloseable et Closeable.
L'interface AutoCloseable a été introduite dans Java 7. Auparavant, il existait une autre interface Appelée Closeable. C'était semblable à ce que les concepteurs de langage voulaient, avec les exceptions suivantes:
Les concepteurs de langage insistent sur la compatibilité ascendante. Étant donné que la modification de l'interface Existante n'était pas souhaitable, ils en ont créé une nouvelle appelée AutoCloseable. Cette nouvelle interface Est moins stricte que Closeable. Puisque Closeable répond aux exigences de AutoCloseable, il a commencé à implémenter AutoCloseable lors de l’introduction de cette dernière.