Pourquoi Eclipse me donne-t-il le message "Fuite de ressources: 'in' n'est jamais fermé" dans le code suivant?
public void readShapeData() {
Scanner in = new Scanner(System.in);
System.out.println("Enter the width of the Rectangle: ");
width = in.nextDouble();
System.out.println("Enter the height of the Rectangle: ");
height = in.nextDouble();
Parce que vous ne fermez pas votre scanner
in.close();
Comme d'autres l'ont déjà dit, vous devez appeler 'close' sur IO classes. J'ajouterai que c'est un excellent endroit pour utiliser l'essai - enfin bloquer sans prise, comme ceci:
public void readShapeData() throws IOException {
Scanner in = new Scanner(System.in);
try {
System.out.println("Enter the width of the Rectangle: ");
width = in.nextDouble();
System.out.println("Enter the height of the Rectangle: ");
height = in.nextDouble();
} finally {
in.close();
}
}
Cela garantit que votre scanner est toujours fermé, garantissant ainsi un nettoyage correct des ressources.
De manière équivalente, dans Java 7 ou supérieur, vous pouvez utiliser la syntaxe "try-with-resources":
try (Scanner in = new Scanner(System.in)) {
...
}
Vous devez appeler in.close()
, dans un bloc finally
, pour vous en assurer.
Dans la documentation Eclipse, voici pourquoi il signale ce problème particulier ( emphase mienne):
Classes implémentant l'interface Java.io.Closeable (depuis JDK 1.5) et Java.lang.AutoCloseable (depuis JDK 1.7) sont considérés comme représentant des ressources externes, qui doivent être fermées à l'aide de la méthode close (), lorsqu'elles ne sont plus nécessaires.
Le compilateur Eclipse Java est capable d'analyser si le code utilisant de tels types adhère à cette stratégie.
...
Le compilateur signalera [violations] avec "La fuite de ressources: le flux n'est jamais fermé".
Explication complète ici .
Cela vous indique que vous devez fermer le scanner que vous avez instancié sur System.in
avec Scanner.close()
. Normalement, chaque lecteur doit être fermé.
Notez que si vous fermez System.in
, vous ne pourrez plus le lire. Vous pouvez également consulter la classe Console
.
public void readShapeData() {
Console console = System.console();
double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: "));
double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: "));
...
}
Si vous utilisez JDK7 ou 8, vous pouvez utiliser try-catch avec des ressources. Ceci fermera automatiquement le scanner.
try ( Scanner scanner = new Scanner(System.in); )
{
System.out.println("Enter the width of the Rectangle: ");
width = scanner.nextDouble();
System.out.println("Enter the height of the Rectangle: ");
height = scanner.nextDouble();
}
catch(Exception ex)
{
//exception handling...do something (e.g., print the error message)
ex.printStackTrace();
}
Vous devriez fermer votre scanner lorsque vous avez terminé:
in.close();
l'ajout de private static Scanner in;
ne résout pas vraiment le problème, il efface simplement l'avertissement. Rendre le scanner statique signifie qu'il reste ouvert pour toujours (ou jusqu'à ce que la classe soit déchargée, ce qui est presque "pour toujours"). Le compilateur ne vous avertit plus, puisque vous lui avez dit "gardez-le ouvert pour toujours". Mais ce n’est pas ce que vous vouliez vraiment, car vous devez fermer les ressources dès que vous n’en avez plus besoin.
HTH, Manfred.
Généralement, les instances de classes traitant d'E/S doivent être fermées une fois que vous avez fini de les utiliser. Donc, à la fin de votre code, vous pouvez ajouter in.close()
.
// An InputStream which is typically connected to keyboard input of console programs
Scanner in= new Scanner(System.in);
la ligne ci-dessus invoquera la classe Constructor of Scanner avec l'argument System.in et renverra une référence à un objet nouvellement construit.
Il est connecté à un flux d'entrée connecté au clavier. Vous pouvez donc, au moment de l'exécution, saisir les entrées de l'utilisateur pour effectuer les opérations requises.
//Write piece of code
Pour supprimer la fuite de mémoire -
in.close();//write at end of code.
private static Scanner in;
Je l'ai corrigé en déclarant en tant que variable de classe Scanner statique privée. Je ne sais pas pourquoi cela a résolu le problème, mais c'est ce que Eclipse m'a recommandé de faire.
Le scanner devrait être fermé. Il est recommandé de fermer les lecteurs, les flux ... et ce type d’objets pour libérer des ressources et éviter les fuites de mémoire. et le faire ensuite dans un bloc pour s’assurer qu’ils sont fermés même si une exception se produit lors de la manipulation de ces objets.
Scanner sc = new Scanner(System.in);
//do stuff with sc
sc.close();//write at end of code.