2014-10-22 7 views
16

Ich habe Code untersucht und ich habe versucht, mit Ressourcen zu versuchen. Ich habe die Standard-Try-Catch-Anweisung zuvor verwendet und es sieht so aus, als würden sie das Gleiche tun. Also meine Frage ist Versuchen Sie mit Ressourcen vs Try-Catch Was sind die Unterschiede zwischen denen, und das ist besser. HierVersuchen Sie mit Ressourcen vs Try-Catch

ist ein Versuch mit Ressourcen:

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

Der Unterschied ist, dass Sie stream.close() in der try-wth-Ressource nicht aufrufen müssen. Es heißt automatisch af, wenn Sie eine finally-Klausel haben, die es schließt. In der try-with-resouce-Klausel können nur Objekte verwendet werden, die Closeable oder AutoCloseable enthalten. – sturcotte06

+2

Sie müssen (oder sollten Sie wahrscheinlich nicht) 'stream.close();' im Abschnitt 'try {..}' aufrufen. Es sollte im 'finally'-Bereich erfolgen, den try-with-resources für Sie übernehmen (BTW-Try-with-resources können mehrere Ressourcen verwalten). – Pshemo

Antwort

26

der wichtigste Punkt der Try-with-Ressourcen, um sicherzustellen, Ressourcen werden geschlossen, ohne dass dafür der Anwendungscode erforderlich ist. Es gibt jedoch einige Feinheiten, die es zu beachten gilt.

Wenn Sie Try-with-resources nicht verwenden, gibt es einen potenziellen Fallstrick namens Exception-masking. Wenn Code in einem try-Block eine Exception auslöst und die close-Methode schließlich auch eine Exception auslöst, geht die vom try-Block ausgelöste Exception verloren, und die Ausnahme, die im try-Block geworfen wird, wird propagiert. Dies ist normalerweise bedauerlich, da die Ausnahme, die auf Schließen geworfen wird, etwas nicht hilfreich ist, während die nützliche Ausnahme die informative Ausnahme ist. Wenn Sie Try-with-resources verwenden, um Ihre Ressourcen zu schließen, wird das Ausschließen von Ausnahmebedingungen verhindert.

Um sicherzustellen, dass Exception-Masking wichtige Ausnahmeinformationen nicht verlieren würde, mussten sie bei der Entwicklung von try-with-resources entscheiden, was mit den Ausnahmen geschehen soll, die von der close-Methode ausgelöst wurden.

Mit Try-with-Ressourcen, wenn der try-Block eine Ausnahme und die enge Methode wirft wirft auch eine Ausnahme, dann the exception from the close block gets tacked on to the original exception:

... es gibt Situationen, in denen zwei unabhängige Ausnahmen können in geworfen werden Geschwistercode-Blöcke, insbesondere im try-Block einer try-with-resources-Anweisung und dem vom Compiler generierten finally-Block, der die Ressource schließt. In diesen Situationen kann nur eine der ausgelösten Ausnahmen propagiert werden. Wenn in der try-with-resources-Anweisung zwei solche Ausnahmen vorhanden sind, wird die vom try-Block stammende Ausnahme weitergegeben, und die Ausnahme vom finally-Block wird zur Liste der Ausnahmen hinzugefügt, die durch die Ausnahme vom try-Block unterdrückt werden. Wenn eine Ausnahme den Stapel abwickelt, können mehrere unterdrückte Ausnahmen akkumuliert werden.

Auf der anderen Seite, wenn Ihr Code wirft auf der Nähe eine Ausnahme mit Ihnen normalerweise aber die Ressource abgeschlossen ist, geworfen wird diese Ausnahme (das unterdrückt bekommen würde, wenn der Code im try-Block alles wirft). Wenn Sie also einen JDBC-Code haben, in dem ein ResultSet oder PreparedStatement durch try-with-resources geschlossen wird, kann eine Ausnahme aufgrund eines Infrastrukturfehlers beim Schließen eines JDBC-Objekts ausgelöst werden und einen Vorgang rückgängig machen, der ansonsten erfolgreich abgeschlossen wurde.

Ohne try-with-resources, ob die Close-Methode Ausnahme ausgelöst wird, ist bis zum Anwendungscode.Wenn es in einem finally-Block ausgelöst wird, wenn der try-Block eine Ausnahme auslöst, maskiert die Ausnahme aus dem finally-Block die andere Ausnahme. Der Entwickler hat jedoch die Möglichkeit, die auf close geworfene Ausnahme abzufangen und nicht zu propagieren.

+0

Ich wünschte, es gäbe ein einfaches Mittel für "finally" -Blöcke, um herauszufinden, welche Ausnahme (falls überhaupt) aus dem "try" geworfen wurde, um die gleiche Art von propagate-clean-up-Ausnahmen zuzulassen, wenn-nein- andere-anstehende Logik im Benutzercode. – supercat

2

Der einzige Unterschied besteht darin, dass Try-Ressource fügt automatisch resource.close(); , wie Sie in finally Block

4

Sie etwas verpaßt, den finally Block tun würden. Die try-with-resouces wird es so etwas wie,

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) { 
    } 
    } 
} 

Was bedeutet, dass Sie so etwas wie (nie schlucken Ausnahmen) wollte wirklich,

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 ist unnötig, da der stream sowieso geschlossen wird. – UDPLover

+0

@Meraman Ich habe das im letzten Teil meiner Antwort notiert. Beachte, dass die Frage von OP * nein * 'endlich 'blockiert ist. –

0

Jedes Objekt (entweder die Klasse oder deren Superklasse), das java.lang.AutoCloseable oder java.io.Closeable implementiert, kann nur in der try-with-resource-Klausel verwendet werden. AutoClosable-Schnittstelle ist die übergeordnete Schnittstelle und Closable-Schnittstelle erweitert die AutoClosable-Schnittstelle. Die AutoClosable-Schnittstelle hat eine Methode zum Schließen, die eine Ausnahme auslöst, während die Closable-Schnittstelle eine Methode hat, die IOException auslöst. Wir können auch catch haben und schließlich blocked gefolgt von try-with-resource wie gewöhnlicher try, catch und finally, aber catch und finally blocked werden nur ausgeführt, sobald die in der try-with-resource-Klausel deklarierte Ressource geschlossen wird.

Verwandte Themen