Frage

Vor diesem Code:

String test() {
    try {
        return "1";
    } finally {
        return "2";
    }
}

Haben die Sprache Spezifikationen definieren Sie den Rückgabewert eines Aufrufs test()? Mit anderen Worten: Ist es immer das gleiche in jeder JVM?

In der Sun JVM ist der Rückgabewert 2, aber ich will sicher sein, dass dies nicht VM abhängig.

War es hilfreich?

Lösung

Ja, die Sprache spec definiert, dass „2“ ist das Ergebnis. Wenn ein VM es anders macht, ist es nicht spec-kompatibel ist.

Die meisten Compiler werden darüber beschweren. Eclipse, zum Beispiel, wird behaupten, dass die Rücklaufsperre wird nie ausgeführt werden, aber es ist falsch.

Es ist erschreckend schlechte Praxis zu schreiben Code wie das, Sie überhaupt es nicht tun:)

Andere Tipps

Ja, die Java Language Specification ist sehr klar zu diesem Thema ( 14.20.2 ):

  

Eine try-Anweisung mit einem finally-Block wird durch erste Ausführung des try-Block ausgeführt. Dann gibt es eine Auswahl:

     
      
  • Wenn die Ausführung der try-Blöcke abgeschlossen ist normal, [...]
  •   
  • Wenn die Ausführung des try-Block beendet abrupt wegen eines Wurfes mit einem Wert von V [...]
  •   
  • Wenn die Ausführung des try-Block plötzlich aus irgendeinem anderen Grund R abgeschlossen ist, dann wird der finally-Block ausgeführt. Dann gibt es eine Auswahl:      
        
    • Wenn das abgeschlossen ist schließlich normalerweise blockieren, [...]
    •   
    • Wenn die endlich abgeschlossen ist Block abrupt Grund S, dann werden die try-Anweisung schließt abrupt Grund S (und Grund R wird verworfen).
    •   
  •   

Der finally-Block wird immer außer im folgende Beispiel ausgeführt werden:

String test() {
    try {
        System.exit(0);
    } finally {
        return "2";
    }
}

In diesem Fall wird die JVM stoppen, ohne den finally Block ausgeführt wird.

So in Ihrem Beispiel der Rückgabewert 2 sein wird.

Ja, wenn Sie etwas aus dem finally Block zurückkehren, wird es ersetzen, was Sie von dem try oder catch Block zurückgegeben haben könnten.

Das gleiche gilt auch für Ausnahmen . Wenn Sie etwas in dem finally Block werfen, wird diese Ausnahme ersetzen, was Ausnahme in dem try oder catch Block geworfen wurde. Seien Sie also vorsichtig, nie etwas in dem finally Block zu werfen, weil es den ursprünglichen Grund für einen Fehler verbergen kann.

Nach der Bytecode von Programm zu lesen, wird der Code wie folgt:

Die finally-Block-Anweisungen werden inlined vor der return-Anweisung von Try-Block, so dass die Rückkehr von dem finally-Block führt einen ersten und die ursprüngliche return-Anweisung nie.

Für Programm:

String test() {
        try {
            System.out.println("try");
            return "1";
        } finally {
            System.out.println("finally");
            return "2";
        }
    }

Er wandelt auf:

String test()
    {
        System.out.println("try");
        String s = "1"; //temporary variable 
        System.out.println("finally");
        return "2";
        Exception exception;
        exception;
        System.out.println("finally");
        return "2";
    }

und Für Programm: mit catch-Block:

String test() {

        try {
            System.out.println("try");
            return "1";
        } catch (RuntimeException e) {
            System.out.println("catch");
            return "2";
        } finally {
            System.out.println("finally");
            return "3";
        }
    }

Wandelt an:

String test()
    {
        System.out.println("try");
        String s = "1";
        System.out.println("finally");
        return "3";
        RuntimeException e;
        e;
        System.out.println("catch");
        String s1 = "2";
        System.out.println("finally");
        return "3";
        Exception exception;
        exception;
        System.out.println("finally");
        return "3";
    }

. Hinweis: Eingewilligt mit JDK 1.7 & dekompilierte mit Cavaj

Sie können die folgenden Link verweisen. Ich hoffe, es wird alle Einzelheiten mit:

http: // www. programmerinterview.com/index.php/java-questions/will-finally-run-after-return/

Es heißt schließlich wird Baustein führt auch immer versuchen, oder Catch-Block hat return-Anweisung. Und wenn schließlich Block hat auch return-Anweisung, dann wird dies die return-Anweisung außer Kraft setzen, die innerhalb Versuch ist oder catch-Block und in diesem Fall eine Ausnahme in try / catch geworfen wird verworfen (schlechter Ansatz) wird.

Über Antwort der ist sehr gut zusammengefasst will nur hier einen weiteren Punkt hinzuzufügen.

private static int divide(int a , int b){
    try{
        return  a/b;
    }finally{
        System.out.println("In finally");
        return 1;
    }
}

Wenn wir die 1,0 dann die obige Methode übergeben wird, die Ausnahme von geworfen unterdrücken und nur das Ergebnis zurück. Sie ist bereits gesagt, sollte der obige Code nicht in der Produktionsumgebung verwendet werden.

  private static int divide(int a , int b){
        int result = 0;
        try{
            result =   a/b;
        }finally{
            System.out.println("In finally");
            result =  1;
        }

        return result;
    }

mit der return-Anweisung nach dem finally-Block wird in Folge

Exception in thread "main" java.lang.ArithmeticException: / by zero
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top