2697 Stimmen

Wird ein finally-Block in Java immer ausgeführt?

Bei diesem Code kann ich sicher sein, dass der finally-Block immer ausgeführt wird, egal was something() ist?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("Ich weiß nicht, ob das ausgegeben wird");
}

672 Stimmen

Wenn dies nicht der Fall ist, sollte das Schlüsselwort wie folgt lauten probably stattdessen.

61 Stimmen

3 Stimmen

Effektives Java sagt etwas anderes informit.com/articles/article.aspx?p=1216151&seqNum=7

0voto

tquadrat Punkte 2151

El akzeptierte Antwort ist in fast allen Aspekten wahr, aber es ist trotzdem nur die halbe Wahrheit (ok, 95% der Wahrheit).

Gehen Sie von folgendem Code aus:

private final Lock m_Lock = new ReentrantLock();
…
public final SomeObject doSomething( final SomeObject arg )
{
  final SomeObject retValue;
  try
  {
    lock.lock();
    retValue = SomeObject( arg );
  }
  finally
  {
    out.println( "Entering finally block");
    callingAnotherMethod( arg, retValue );
    lock.unlock();
  }

  return retValue;
}
…
try
{
   final var result = doSomething( new SomeObject() );
}
catch( final StackOverflowError e ) { /* Deliberately ignored */ }

Aufruf der Methode doSomething() wird eine StackOverflowError fast sofort.

Und die lock wird nicht veröffentlicht!

Aber wie konnte dies geschehen, wenn die finally Block wird immer ausgeführt (mit den Ausnahmen, die bereits in der akzeptierte Antwort )?

Das liegt daran, dass es eine keine Garantie gemacht, dass alle Aussagen im finally Block sind wirklich ausgeführt!

Dies wäre offensichtlich, wenn es einen Aufruf zu System.exit() oder eine throws Anweisung vor dem Aufruf von lock.unlock() .

Aber im Beispielcode ist nichts dergleichen zu finden

Abgesehen davon, dass die beiden anderen Methodenaufrufe in der finally Block vor dem Aufruf von lock.unlock() wird eine weitere StackOverflowError

Und voilà, die Sperre wird nicht aufgehoben!

Obwohl der Beispielcode an sich albern ist, lassen sich ähnliche Muster in vielen Arten von Software finden. Alles funktioniert gut, solange nichts Hässliches in der finally blockieren

Lustige Tatsache ist, dass es nicht funktioniert in späteren Versionen von Java (was bedeutet, dass in späteren Versionen, die Sperre wurde freigegeben ). Keine Ahnung, wann und warum dies geändert.

Aber Sie müssen trotzdem sicherstellen, dass die finally Block immer normal beendet wird, sonst könnte es egal sein, ob (dass) er immer ausgeführt wird

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X