2012-09-20 5 views
60

Perché Eclipse mi dà il riscaldamento "Perdita di risorse:" in "non viene mai chiuso" nel seguente codice?Perdita di risorsa: "in" non viene mai chiuso

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(); 

risposta

43

Perché non si chiude lo Scanner

in.close(); 
+28

Questo chiude la 'Scanner' e mettere a tacere l'avvertimento, ma sarà anche vicino' System.in' che non è in genere desiderabile. –

+0

@StuartCook +1. Qualcosa da tenere d'occhio. – informatik01

+3

Perché abbiamo bisogno di chiudere Scanner? Cosa si intende per "perdita di risorse"? –

3

Si dovrebbe close vostro scanner quando hai finito con esso:

in.close(); 
2

In generale, istanze di classi che si occupano di L'I/O dovrebbe essere chiuso dopo aver finito con loro. Quindi alla fine del tuo codice potresti aggiungere in.close().

6

Si sta dicendo che è necessario chiudere lo scanner istanziato su System.in con Scanner.close(). Normalmente ogni lettore dovrebbe essere chiuso.

Si noti che se si chiude System.in, non sarà possibile leggerlo nuovamente. Puoi anche dare un'occhiata alla 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: ")); 
    ... 
} 
+2

Nota che 'System.console() 'non è disponibile quando si esegue un'applicazione tramite Eclipse, che può essere una seccatura durante lo sviluppo. –

0

Lo scanner deve essere chiuso. È una buona pratica chiudere Lettori, Strati ... e questo tipo di oggetti per liberare risorse e perdite di memoria; e facendo così in un blocco finally per assicurarsi che siano chiusi anche se si verifica un'eccezione durante la gestione di tali oggetti.

+0

Questa risposta aiuta effettivamente OP a sapere perché dovrebbe chiudere la cosa. Certo, può leggere il documento e vedere "' scanner.close() '", ma questa risposta lo aiuta davvero a capire cosa sta succedendo. + 1 – HyperNeutrino

36

Come altri hanno già detto, è necessario chiamare "chiudi" nelle classi IO. Io aggiungo che questo è un ottimo posto per usare il tentativo - blocco finally senza detenere catture, in questo modo:

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(); 
    } 
} 

questo assicura che lo scanner sia sempre chiusa, garantendo una corretta pulizia delle risorse.

equivalente, in Java 7 o superiore, è possibile utilizzare la sintassi "try-with-risorse":

try (Scanner in = new Scanner(System.in)) { 
    ... 
} 
+1

Cosa si intende per perdita di risorse e in che modo mi riguarda? –

+4

@Borat - "perdita di risorse" implica che alcune risorse di sistema (di solito la memoria) vengono perse o sprecate inutilmente. Di solito questo ha un impatto su di te quando inizi a generare OutOfMemoryErrors durante il normale funzionamento del tuo programma. –

+0

Grazie eric. So che puoi causare l'errore aggiungendo una stringa a se stessa in un ciclo infinito. Non sono sicuro di come uno scanner possa causare questo errore. –

0
private static Scanner in; 

ho riparato dichiarando come una variabile di classe scanner private static. Non sono sicuro del motivo per cui è stato corretto, ma questo è ciò che Eclipse mi ha consigliato.

+2

hai disattivato l'avviso ma hai creato una perdita di risorse – zacheusz

8

È necessario chiamare in.close(), in un blocco finally per assicurarsi che si verifichi.

Dalla documentazione Eclipse, ecco il motivo per cui IT bandiere questo particolare problema (enfasi mio):

classi che implementano l'interfaccia java.io.Closeable (dal JDK 1.5) e java.lang.AutoCloseable (dal JDK 1.7) sono considerati rappresentano risorse esterne, che devono essere chiuse utilizzando il metodo close(), quando non sono più necessarie.

Il compilatore Java Eclipse è in grado di analizzare se il codice che utilizza tali tipi aderisce a questa politica.

...

Il compilatore bandiera [violazioni] con "La perdita di risorsa: 'flusso' non è mai chiusa".

Spiegazione completa here.

1

l'aggiunta di private static Scanner in; non risolve il problema, elimina solo l'avviso. Rendere statico lo scanner significa che rimane aperto per sempre (o fino a quando la lezione viene scaricata, che è quasi "per sempre"). Il compilatore non ti avvisa più, dal momento che gli hai detto "tienilo aperto per sempre". Ma non è quello che volevi davvero, dal momento che dovresti chiudere le risorse non appena non ne hai più bisogno.

HTH, Manfred.

3

Se si utilizza JDK7 o 8, è possibile utilizzare try-catch con risorse. Ciò consente di chiudere automaticamente lo 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(); 
} 
0
in.close(); 
scannerObject.close(); 

Si chiuderà Scanner e chiudere l'avviso.

2
Scanner sc = new Scanner(System.in); 

//do stuff with sc 

sc.close();//write at end of code. 
3
// An InputStream which is typically connected to keyboard input of console programs 

Scanner in= new Scanner(System.in); 

sopra linea invocherà Costruttore di classe scanner con l'argomento System.in, e tornerà un riferimento all'oggetto di nuova costruzione.

È collegato a un flusso di input collegato alla tastiera, quindi ora in fase di esecuzione è possibile eseguire l'input dell'utente per eseguire le operazioni necessarie.

//Write piece of code 

Per rimuovere la perdita di memoria -

in.close();//write at end of code.