Frage

Gibt es einen funktionalen Unterschied?

Connection c = null;
try {
  c = getConnection();
  c.doStuff();
} finally {
  if (c!=null) c.close();
}

vs

Connection c = null;
c = getConnection();
c.doStuff();
try {
} finally {
  if (c!=null) c.close();
}

vs

Connection c = null;
try {
  c = getConnection();
} finally {
  if (c!=null) c.close();
}
c.doStuff();

Ich habe das Gefühl, dass sie alle in jedem Fall das Gleiche tun werden

War es hilfreich?

Lösung

Eine Ausnahme, die außerhalb von a auftritt try-finally Block ist per Definition ein unbehandelte Ausnahme.In diesem Fall haben Sie keine Garantie dafür, wie das Betriebssystem oder die Laufzeit damit umgehen.Die Chancen stehen gut, dass keine Ausnahmeabwicklung ausgelöst wird, Ihr Code einfach abbricht (vielleicht beschreibt abend es in dieser Diskussion besser – „abnormales Ende“), und Ihr Code wird einfach abgebrochen finally Block wird niemals ausgeführt.

Der Punkt von try-finally soll garantieren, dass die Codebereinigung erfolgt, und zwar im richtigen Kontext.

Sie müssen denken, dass der Code in der finally Der Block wird immer ausgeführt, egal was passiert, und er wird ausgeführt, nachdem die gesamte Methode abgeschlossen ist. Daher spielt es keine Rolle, ob sich der andere Code innerhalb oder außerhalb des Blocks befindet try-finally konstruieren, aber das ist nicht korrekt.

Wenn Sie also Laufzeitgarantien für korrektes Verhalten wünschen, ist Ihr erstes Beispiel das einzig richtige.

  • In Ihrem ersten Beispiel erwerben Sie und was noch wichtiger ist verwenden eine Verbindung (zu einer Datenbank, würde man annehmen) innerhalb der try Block.Wenn eine Ausnahme innerhalb der auftritt try Block, dann die finally Der Block wird ausgeführt und Ihre Verbindung geschlossen.

  • In Ihrem zweiten Beispiel wird Ihr Anschluss komplett außerhalb des erfasst und genutzt try-catch bauen.Wenn bei der Verbindung eine Ausnahme auftritt, wird wahrscheinlich der gesamte Kontext verworfen finally Der Block wird nicht ausgeführt und Ihre Verbindung wird nicht geschlossen.

  • In Ihrem dritten Beispiel: finally wird danach ausgeführt try, aber vor jedem Code, der nach dem kommt finally Block.Beim Versuch, die Verbindung zu verwenden, wird eine Ausnahme generiert, da die Verbindung bereits explizit geschlossen wurde.

Andere Tipps

craig hat sich bereits an das unbehandelte Ausnahmeproblem angesprochen, aber ich wollte es klarstellen.Ich habe zwei Beispiele kodiert (das letzte ist nur schlecht, weil Sie mit einer unterbrochenen Verbindung nach einer Ausnahme arbeiten könnten, nicht wahr werden).Hier ist ein einfaches Beispiel, das einen ArrayIndexoutoNoundsexception auswirkt:

generasacodicetagpre.

und hier ist die Ausführung:

generasacodicetagpre.

Wie Sie in der ersten Version sehen können, wurde ein Ausnahmet-Handler registriert, da die Ausnahme im Kontext eines Versuchsblocks aufgetreten ist.In der zweiten Version gab es keinen registrierten Ausnahmehandler und der Standardausnahme-Handler wurde aufgerufen (dh eine nicht erfasste Ausnahme).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top