Heim  >  Artikel  >  Java  >  Einige Hinweise zur Verwendung der Java-finally-Anweisung

Einige Hinweise zur Verwendung der Java-finally-Anweisung

零下一度
零下一度Original
2017-06-25 10:44:151527Durchsuche

Es gibt viele Leute im Internet, die darüber diskutieren, ob die final-Anweisung im try...catch...finally-Block des Ausnahmeabfangmechanismus in Java definitiv ausgeführt wird? Viele Leute sagen nein, natürlich ist ihre Antwort richtig. Nach meinen Experimenten gibt es mindestens zwei Situationen, in denen die final-Anweisung nicht ausgeführt wird:

(1) Die try-Anweisung wird nicht ausgeführt, wie zum Beispiel It kehrt vor der try-Anweisung zurück, sodass die final-Anweisung nicht ausgeführt wird. Dies zeigt auch, dass die notwendige, aber nicht ausreichende Bedingung für die Ausführung der final-Anweisung ist: Die entsprechende try-Anweisung muss ausgeführt werden.

(2) Es gibt eine Anweisung wie System.exit(0); im try-Block wird die JVM beendet. Natürlich wird die final-Anweisung nicht ausgeführt.

Natürlich diskutieren viele Leute über die Beziehung zwischen der Ausführung der „Finally“-Anweisung und der Rückkehr, was ziemlich verwirrend ist. Ich frage mich, ob die „final“-Anweisung vor oder nach der Rückkehr des Versuchs ausgeführt wird. Ich bin auch verwirrt, was sie gesagt haben. Ich denke, es sollte so sein: Die „final“-Anweisung wird ausgeführt, nachdem die „try return“-Anweisung ausgeführt wurde und bevor die „return“-Anweisung zurückgegeben wird. Diese Aussage ist etwas widersprüchlich. Im Folgenden gebe ich einige Ergebnisse und Beispiele meiner eigenen Experimente. Wenn Sie Fragen haben, können Sie diese gerne stellen.

1. Die „final“-Anweisung wird nach der Ausführung der „return“-Anweisung und vor „return“ ausgeführt.

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest1 {

    public static void main(String[] args) {
        
        System.out.println(test1());
    }

    public static int test1() {
        int b = 20;

        try {
            System.out.println("try block");

            return b += 80; 
        }
        catch (Exception e) {

            System.out.println("catch block");
        }
        finally {
            
            System.out.println("finally block");
            
            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }
        }
        
        return b;
    }
    
}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

Das Laufergebnis ist:

try block
finally block
b>25, b = 100
100

gibt an, dass die Return-Anweisung vor der Ausführung der Final-Anweisung ausgeführt wurde. Sie kehrt jedoch nicht direkt zurück, sondern wartet auf die Ausführung der Final-Anweisung, bevor das Ergebnis zurückgegeben wird .

Wenn Sie der Meinung sind, dass dieses Beispiel nicht ausreicht, um die Situation zu erklären, finden Sie hier ein weiteres Beispiel, um die Schlussfolgerung zu untermauern:

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest1 {

    public static void main(String[] args) {
        
        System.out.println(test11());
    }
    
    public static String test11() {
        try {
            System.out.println("try block");

           return test12();
      } finally {
           System.out.println("finally block");
       }
  }

  public static String test12() {
       System.out.println("return statement");

       return "after return";
   }
    
}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

Das laufende Ergebnis ist:

try block
return statement
finally block
after return

Es bedeutet, dass die Return-Anweisung in try wird zuerst ausgeführt, aber es wird nicht sofort zurückgegeben.

Sie denken vielleicht: Wenn es eine return-Anweisung gibt, kann try nicht direkt zurückgegeben werden zurückgegeben werden? Siehe unten.

2. Die Return-Anweisung im Final-Block überschreibt die Return-Anweisung im Try-Block.

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest2 {

    public static void main(String[] args) {

        System.out.println(test2());
    }

    public static int test2() {
        int b = 20;

        try {
            System.out.println("try block");

            return b += 80;
        } catch (Exception e) {

            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            return 200;
        }

        // return b;
    }

}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

Das Laufergebnis ist:

try block
finally block
b>25, b = 100
200

Dies bedeutet, dass die Rückgabe direkt erfolgt, unabhängig davon, ob eine Rückgabeanweisung in try vorhanden ist. Nach dem Hinzufügen von return to muss darauf geachtet werden endlich, endlich Die äußere Rückgabe b wird zu einer nicht erreichbaren Anweisung, das heißt, sie kann nie ausgeführt werden, daher muss sie auskommentiert werden, sonst meldet der Compiler einen Fehler.

Hier denken Sie vielleicht auch: Wenn es in „finally“ keine Return-Anweisung gibt, aber der Wert von b geändert wird, gibt die Rückgabe in „try“ dann den geänderten Wert oder den ursprünglichen Wert zurück? Siehe unten.

3. Wenn in der „final“-Anweisung keine Return-Anweisung zum Überschreiben des Rückgabewerts vorhanden ist, kann sich der ursprüngliche Rückgabewert aufgrund der Änderung in „final“ ändern oder auch nicht.

Testfall 1:

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest3 {

    public static void main(String[] args) {

        System.out.println(test3());
    }

    public static int test3() {
        int b = 20;

        try {
            System.out.println("try block");

            return b += 80;
        } catch (Exception e) {

            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            b = 150;
        }

        return 2000;
    }

}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

Das Laufergebnis ist:

try block
finally block
b>25, b = 100
100

Testfall 2:

Einige Hinweise zur Verwendung der Java-finally-Anweisung
import java.util.*;

public class FinallyTest6
{
    public static void main(String[] args) {
        System.out.println(getMap().get("KEY").toString());
    }
     
    public static Map<string> getMap() {
        Map<string> map = new HashMap<string>();
        map.put("KEY", "INIT");
         
        try {
            map.put("KEY", "TRY");
            return map;
        }
        catch (Exception e) {
            map.put("KEY", "CATCH");
        }
        finally {
            map.put("KEY", "FINALLY");
            map = null;
        }
         
        return map;
    }
}</string></string></string>
Einige Hinweise zur Verwendung der Java-finally-Anweisung

运行结果是:

FINALLY

为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了,具体请看精选30道Java笔试题解答,里面有详细的解答,简单来说就是:Java中只有传值没有传址,这也是为什么map = null这句不起作用。这同时也说明了返回语句是try中的return语句而不是 finally外面的return b;这句,不相信的话可以试下,将return b;改为return 294,对原来的结果没有一点影响。

这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?请看下面。

4. try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况。

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest4 {

    public static void main(String[] args) {

        System.out.println(test4());
    }

    public static int test4() {
        int b = 20;

        try {
            System.out.println("try block");

            b = b / 0;

            return b += 80;
        } catch (Exception e) {

            b += 15;
            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            b += 50;
        }

        return 204;
    }

}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

运行结果是:

try block
catch block
finally block
b>25, b = 35
85
这里因 为在return之前发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch 语句和最终的finally语句,此时两者对b的修改都影响了最终的返回值,这时return b;就起到作用了。当然如果你这里将return b改为return 300什么的,最后返回的就是300,这毋庸置疑。

这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?看下面。

5. 当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样。

Einige Hinweise zur Verwendung der Java-finally-Anweisung
public class FinallyTest5 {

    public static void main(String[] args) {

        System.out.println(test5());
    }

    public static int test5() {
        int b = 20;

        try {
            System.out.println("try block");
            
            b = b /0;

            return b += 80;
        } catch (Exception e) {

            System.out.println("catch block");
            return b += 15;
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            b += 50;
        }

        //return b;
    }

}
Einige Hinweise zur Verwendung der Java-finally-Anweisung

运行结果如下:

try block
catch block
finally block
b>25, b = 35
35

说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。

 

最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。

学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群:159610322   我们一起学Java!

Das obige ist der detaillierte Inhalt vonEinige Hinweise zur Verwendung der Java-finally-Anweisung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn