2014-10-22 15 views
16

Ho visto il codice e ho visto provare con le risorse. Ho usato la dichiarazione try-catch standard prima e sembra che facciano la stessa cosa. Quindi la mia domanda è Provare con le risorse vs Try-Catch quali sono le differenze tra queste e quale è meglio.Prova con risorse contro Try-Catch

Ecco una prova con le risorse:

objects jar = new objects("brand"); 
objects can= new objects("brand"); 

try (FileOutputStream outStream = new FileOutputStream("people.bin")){ 
    ObjectOutputStream stream = new ObjectOutputStream(outStream); 

    stream.writeObject(jar); 
    stream.writeObject(can); 

    stream.close(); 
    } catch(FileNotFoundException e) { 
     System.out.println("sorry it didn't work out"); 
    } catch(IOException f) { 
     System.out.println("sorry it didn't work out"); 
    } 
+3

la differenza è che non è necessario chiamare stream.close() nella risorsa try-wth. Si chiama automaticamente af se hai una clausola finale che la chiude. Solo gli oggetti che impiantano Closeable o AutoCloseable possono essere utilizzati nella clausola try-with-Resuce. – sturcotte06

+2

Non è necessario (o molto probabilmente non dovrebbe) chiamare 'stream.close();' nella sezione 'try {..}'. Dovrebbe essere fatto nella sezione 'finally' che try-with-resources gestirà per te (BTW try-with-resources può gestire più risorse). – Pshemo

risposta

26

Il punto principale di try-with-risorse è quello di assicurarsi le risorse sono chiuse, senza richiedere il codice dell'applicazione per farlo. Ci sono alcuni punti migliori da considerare, però.

Quando non si utilizza try-with-resources, c'è una potenziale trappola chiamata mascheramento delle eccezioni. Quando il codice in un blocco try genera un'eccezione e anche il metodo close in infine genera un'eccezione, l'eccezione generata dal blocco try viene persa e l'eccezione generata infine viene propagata. Questo di solito è sfortunato, poiché l'eccezione lanciata alla chiusura è qualcosa di inutile mentre l'utile eccezione è quella informativa. L'utilizzo di try-with-resources per chiudere le risorse impedirà l'esecuzione di qualsiasi mascheramento delle eccezioni.

Come parte del fare in modo che il mascheramento delle eccezioni non perda importanti informazioni sulle eccezioni, quando è stato sviluppato try-with-resources hanno dovuto decidere cosa fare con le eccezioni generate dal metodo close.

Con try-con-le risorse, se il blocco try genera un'eccezione e il metodo close lancia anche un'eccezione, quindi the exception from the close block gets tacked on to the original exception:

... ci sono situazioni in cui due eccezioni indipendenti possono essere gettati in blocchi di codice fratello, in particolare nel blocco try di un'istruzione try-with-resources e il blocco finally generato dal compilatore che chiude la risorsa. In queste situazioni, solo una delle eccezioni generate può essere propagata. Nell'istruzione try-with-resources, quando esistono due eccezioni di questo tipo, l'eccezione proveniente dal blocco try viene propagata e l'eccezione dal blocco finally viene aggiunta all'elenco delle eccezioni soppresse dall'eccezione dal blocco try. Come un'eccezione svolge lo stack, può accumulare più eccezioni soppresse.

D'altra parte, se il codice completa normalmente, ma la risorsa che si sta utilizzando genera un'eccezione su una stretta, si butta tale eccezione (che andrebbe soppresso se il codice nel blocco try ha gettato nulla). Pertanto, se si dispone di un codice JDBC in cui un ResultSet o PreparedStatement viene chiuso da try-with-resources, può essere generata un'eccezione risultante da un problema tecnico dell'infrastruttura quando un oggetto JDBC viene chiuso e può eseguire il rollback di un'operazione completata correttamente.

Senza try-with-resources se l'eccezione del metodo close viene generata è fino al codice dell'applicazione.Se viene lanciato in un blocco finally quando il blocco try genera un'eccezione, l'eccezione dal blocco finally maschera l'altra eccezione. Ma lo sviluppatore ha la possibilità di catturare l'eccezione generata da vicino e non propagarla.

+0

Vorrei che ci fosse un mezzo facile per i blocchi "finally" per scoprire quale eccezione (se presente) è stata lanciata dal "try", in modo da consentire lo stesso tipo di propagate-clean-up-exceptions-if-no- altri sono in attesa di logica nel codice utente. – supercat

2

L'unica differenza è che cercare di risorse è l'aggiunta automaticamente resource.close(); come si farebbe in finally blocco

4

vi siete persi qualcosa, il blocco finally. Il try-with-resouces renderà qualcosa di simile,

FileOutputStream outStream = null; 
try { 
    outStream = new FileOutputStream("people.bin"); 
    ObjectOutputStream stream = new ObjectOutputStream(outStream); 

    stream.writeObject(jar); 
    stream.writeObject(can); 

    stream.close(); 
} catch(FileNotFoundException e) { 
    System.out.println("sorry it didn't work out"); 
} catch(IOException f) { 
    System.out.println("sorry it didn't work out"); 
} finally { 
    if (outStream != null) { 
    try { 
     outStream.close(); 
    } catch (Exception e) { 
    } 
    } 
} 

Il che significa che si voleva davvero qualcosa di simile (mai eccezioni rondine),

try (FileOutputStream outStream = new FileOutputStream("people.bin"); 
    ObjectOutputStream stream = new ObjectOutputStream(outStream);) { 
    stream.writeObject(jar); 
    stream.writeObject(can); 
    // stream.close(); // <-- closed by try-with-resources. 
} catch(FileNotFoundException e) { 
    System.out.println("sorry it didn't work out"); 
    e.printStackTrace(); 
} catch(IOException f) { 
    System.out.println("sorry it didn't work out"); 
    e.printStackTrace(); 
} 
+0

stream.close(); in try block non è necessario, in quanto lo stream verrà chiuso nel blocco finale in ogni caso. – UDPLover

+0

@Meraman ho notato che nell'ultima parte della mia risposta. Nota che la domanda dell'OP ha * no * 'finally' block. –

0

Qualsiasi oggetto (classe o superclasse) che implementa java.lang.AutoCloseable o java.io.Closeable può essere utilizzato solo nella clausola try-with-resource. L'interfaccia AutoClosable è l'interfaccia genitore e l'interfaccia Closable estende l'interfaccia AutoClosable. L'interfaccia AutoClosable ha il metodo close che genera l'eccezione mentre l'interfaccia Closable ha il metodo che genera IOException. Possiamo anche avere catch e finally block seguito da try-with-resource come try normale, catch e, infine, ma catch e finally block vengono eseguiti solo una volta che la risorsa dichiarata all'interno della clausola try-with-resource è chiusa.