¿Por qué Eclipse me da la advertencia "Fuga de recursos: 'in' nunca se cierra" en el siguiente código?
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();
Scanner
y silenciará la advertencia, pero también cerrará, loSystem.in
que normalmente no es deseable.System.in
generalmente no es deseable. Es porque no podrás volver a leerlo. I. e. obtendrájava.util.NoSuchElementException: No line found
si intenta llamar,(new Scanner(System.in)).nextLine()
por ejemplo.Como han dicho otros, debe llamar a "cerrar" en las clases de IO. Agregaré que este es un excelente lugar para usar el intento, finalmente bloquear sin captura, como este:
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(); } }
Esto asegura que su escáner esté siempre cerrado, garantizando una limpieza adecuada de los recursos.
De manera equivalente, en Java 7 o superior, puede utilizar la sintaxis "try-with-resources":
try (Scanner in = new Scanner(System.in)) { ... }
fuente
Necesita llamar
in.close()
, en unfinally
bloque para asegurarse de que ocurra.De la documentación de Eclipse, he aquí por qué señala este problema en particular (el énfasis es mío):
Explicación completa aquí .
fuente
Se le está diciendo que necesita cerrar el escáner que ejemplarizado en
System.in
laScanner.close()
. Normalmente, todos los lectores deben estar cerrados.Tenga en cuenta que si cierra
System.in
, no podrá volver a leerlo. También puede echar un vistazo a laConsole
clase.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: ")); ... }
fuente
System.console()
no está disponible cuando se ejecuta una aplicación a través de Eclipse, lo que puede resultar complicado durante el desarrollo.Si está usando JDK7 u 8, puede usar try-catch con recursos. Esto cerrará automáticamente el escáner.
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(); }
fuente
try
como se muestra y no usar unacatch
cláusula.// An InputStream which is typically connected to keyboard input of console programs Scanner in= new Scanner(System.in);
La línea anterior invocará al Constructor de la clase Scanner con el argumento System.in, y devolverá una referencia al objeto recién construido.
Está conectado a un flujo de entrada que está conectado al teclado, por lo que ahora, en tiempo de ejecución, puede tomar la entrada del usuario para realizar la operación requerida.
//Write piece of code
Para eliminar la pérdida de memoria:
in.close();//write at end of code.
fuente
Debería cerrar su escáner cuando haya terminado con él:
fuente
agregar
private static Scanner in;
realmente no soluciona el problema, solo borra la advertencia. Hacer que el escáner sea estático significa que permanece abierto para siempre (o hasta que se descargue la clase, lo que casi es "para siempre"). El compilador ya no le da más advertencia, ya que le dijo "manténgalo abierto para siempre". Pero eso no es lo que realmente deseaba, ya que debería cerrar los recursos tan pronto como ya no los necesite.HTH, Manfred.
fuente
Generalmente, las instancias de clases que se ocupan de E / S deben cerrarse una vez que haya terminado con ellas. Entonces, al final de su código, podría agregar
in.close()
.fuente
private static Scanner in;
Lo arreglé declarando como una variable de clase de escáner estática privada. No estoy seguro de por qué eso lo solucionó, pero eso es lo que eclipse recomendó que hiciera.
fuente
El escáner debe estar cerrado. Es una buena práctica cerrar Readers, Streams ... y este tipo de objetos para liberar recursos y ávidas pérdidas de memoria; y hacerlo en un bloque final para asegurarse de que estén cerrados incluso si se produce una excepción al manipular esos objetos.
fuente
scanner.close()
", pero esta respuesta realmente le ayuda a entender lo que está pasando. + 1De acuerdo, en serio, al menos en muchos casos, esto es en realidad un error. También aparece en VS Code, y el linter se da cuenta de que ha alcanzado el final del alcance adjunto sin cerrar el objeto del escáner, pero sin reconocer que cerrar todos los descriptores de archivos abiertos es parte de la terminación del proceso. No hay pérdida de recursos porque todos los recursos se limpian al finalizar, y el proceso desaparece, sin dejar ningún lugar para que el recurso se mantenga.
fuente
Scanner sc = new Scanner(System.in); //do stuff with sc sc.close();//write at end of code.
fuente
Cerrará
Scanner
y cerrará la advertencia.fuente