2016-09-29 6 views
0

Pause funktioniert nicht in versuchen mit Ressourcen, aber arbeiten in versuchen ohne Ressourcen!
Dies ist ein einfaches Beispiel für diese Situation. Ich habe diesen "Bug" im Arbeitsprojekt entdeckt. Wenn ich versuche, verwenden, ohne RessourcenPause funktioniert nicht in versuchen mit Ressourcen, aber in Versuch ohne Ressourcen arbeiten

try { 
Resources resources = getResources() 
// some code here, look below 
} 

Ich habe nur eine Wiederholung meines Zyklus, und es ist richtig, weil ich die Bedingung „wenn sie wahr ist, dann brechen“, aber wenn ich versuche, ohne Rückgriff auf mit Ressourcen geändert versuchen.

try (Resources resources = getResources()) { 
    // some code here, look below 
} 

Ich war schockiert! Der Zyklus wurde endlos! Warum?

Voll Code:

public class Test { 
      public static void testTryWithResAndBreak() { 
       while (true) { 
        System.out.println("we are in (while(true))"); 
        try (Resources resources = getResources()) { 
         System.out.println("We are in try block"); 
         if (true) { 
          System.out.println("We are in the if(true) now! Next step is break"); 
          break; 
         } 
         System.out.println("OOOOO___OOOO WE ARE HERE!!!"); 
         resources.writeSomething(); 
        } catch (Exception e) { 
         System.out.println("Catched exception"); 
        } 
       } 
      } 
      private static class Resources implements AutoCloseable { 
       @Override 
       public void close() throws Exception { 
        System.out.println("Resources closed"); 
        throw new Exception("Exception after closed resources!"); 
       } 

       public void writeSomething() { 
        System.out.println("i wrote something"); 
       } 
      } 

      private static Resources getResources() { 
       return new Resources(); 
      } 

      public static void main(String[] args) { 
       testTryWithResAndBreak(); 
      } 
     } 
+0

'if (true) {...}' kann vom Compiler entfernt werden. Hast du dort einen tatsächlichen Zustand? – pablochan

+0

Zeigen Sie die andere Version, etwas sagt mir, dass Sie nicht in der Nähe anrufen. –

+0

@pablochan warum? Pause hat nicht funktioniert? Wenn der Compiler meine Bedingung gelöscht hat, löschte er nicht "break". Wenn zum Beispiel (wahr) {"etwas tun"} optimiert wird, wird es einfach "etwas tun". – GermanSevostyanov

Antwort

1

Der Zyklus ist endlos, weil Ihr nahe am Ende des try Umfang auftreten. Dies löst eine Ausnahme aus, die den Break-Vorgang unterbricht. Der Ausnahmebehandler (der INSIDE in der while-Schleife ist) fängt ihn dann ab und fährt bis zum Ende der Schleife fort, und da die Schleifenbedingung "wahr" ist, wird sie für immer fortgesetzt. Wenn Sie try-with-resource nicht verwenden, wird der close nie aufgerufen, sodass die Ausnahme nicht ausgelöst wird und die Unterbrechung nicht unterbrochen wird.

+0

http://pastebin.com/zJfLBBp9 Beispiel mit "versuche mit Ressourcen", und dieses http://pastebin.com/4bS5Vatr Beispiel ohne Ressourcen.:) Im ersten Beispiel funktioniert Pause, aber im zweiten Beispiel funktioniert nicht :( – GermanSevostyanov

0

Kurz bevor die break ausgeführt wird, wird die close Methode auf der Resource aufgerufen. Dies kann in dem Byte-Code zu sehen:

L9 // Print statement 
    LINENUMBER 14 L9 
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 
    LDC "We are in the if(true) now! Next step is break" 
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V 
    L1 // Close method call 
    LINENUMBER 17 L1 
    ALOAD 2 
    IFNULL L10 
    ALOAD 2 
    INVOKEVIRTUAL Main$Resources.close()V 
    L3 // Then the break 
    LINENUMBER 15 L3 
    GOTO L10 

Aber diese close Methode löst eine Ausnahme selbst, die Kontrolle über die an den catch Block überträgt. Nachdem der catch Block fertig ist, setzt die while Schleife ihre nächste Iteration fort. Daher wird die break-Anweisung niemals ausgeführt.

Die Struktur, die durch die Try-with-Ressourcen sieht ungefähr so ​​aus:

try { 
    Resources resources = null; 
    try { 
     resources = getResources(); 
     if (true) { 
      break; 
     } 
    } catch (Exception e) {    
    } finally { 
     if(resources != null) 
      resources.close(); 
    } 
} catch (Exception e) { 
} 

Dies unterscheidet sich von Ihrer Version, wo der innere finally Block bereits die Ausnahme behandelt, wonach der break ausgeführt wird. Aber oben wird die Ausnahme durch den äußeren catch Block behandelt, nach dem die Kontrolle an die while Schleife zurückgegeben wird.

+0

, wenn ich Fang wie folgt geändert habe http://pastebin.com/4bS5Vatr, ich habe endlosen Zyklus zu – GermanSevostyanov

+0

können Sie mich beschreiben, warum? – GermanSevostyanov

+0

"Aber diese close-Methode löst selbst eine Ausnahme aus, die die Kontrolle auf den catch-Block überträgt." Aber die Methode close() muss nach dem try-Block ausgeführt werden, oder? Und die "Pause" im try-Block. – GermanSevostyanov

Verwandte Themen