Maison  >  Article  >  Java  >  Analyse de l'ordre d'exécution de enfin et retour en Java (exemple de code)

Analyse de l'ordre d'exécution de enfin et retour en Java (exemple de code)

不言
不言original
2018-09-11 14:16:021623parcourir

Ce que cet article vous apporte concerne l'analyse de la séquence d'exécution (exemples de code) de final et return en Java. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Nous connaissons tous les caractéristiques d'exécution de enfin

1 Qu'il y ait ou non une exception, le code du bloc final sera exécuté

2. est de retour dans try and catch , sera finalement toujours exécuté.

Alors la question est : quel est l'ordre d'exécution ?

Une classe de test simple et un bytecode décompilé :

public class Test {
         publicstatic void main(String[] args) {
             System.out.println(test());
         }
 
         publicstatic int test() {
                   try{
                            System.out.println("Codesin try block.");
                            return0;
                   }catch (Exception e) {
                            System.out.println("Codesin catch block.");
                            return100;
                   }finally {
                            System.err.println("Codesin finally block.");
                   }
         }
}
/*
 public static int test();
   Code:
      0: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
      3: ldc           #5                  // String Codes in try block.
      5: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      8: iconst_0
      9: istore_0
     10: getstatic     #7                  // Field java/lang/System.err:Ljava/io/PrintStream;
     13: ldc           #8                  // String Codes in finallyblock.
     15: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     18: iload_0
     19: ireturn
     20: astore_0
     21: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
     24: ldc           #10                 // String Codes in catchblock.
     26: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     29: bipush        100
     31: istore_1
     32: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     35: ldc           #8                  // String Codes in finallyblock.
     37: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     40: iload_1
     41: ireturn
     42: astore_2
     43: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     46: ldc           #8                  // String Codes in finallyblock.
     48: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     51: aload_2
     52: athrow
*/

Vous pouvez comparer le code que nous avons écrit avec le bytecode compilé :

Analyse de lordre dexécution de enfin et retour en Java (exemple de code)

J'ai trouvé que la machine virtuelle a fait beaucoup de choses pour nous. Elle a inséré le bloc d'instructions final entre les instructions try, catch et return. C'est pourquoi final sera exécuté indépendamment du fait qu'il y ait une exception ou non, qu'elle revienne ou non. Puisque finalement sera exécuté, alors tout ce qui est renvoyé est finalement ce qui est renvoyé. Puisque tous les retours avant finalement ne sont pas valides, quelle est la signification de retour Par conséquent, dans la pratique, les blocs final ne sont pas autorisés à revenir. Le compilateur Eclipse affichera un avertissement : finalblock ne se termine pas normalement.

Code de test pour plusieurs situations

try{ return; }catch(){} enfin{} return;

Code de test :

1. Type de données de base

   public static int test1(){
      int a = 10;
      try{
         a = 20;
         return a;
      }catch(Exception e){
         //other codes.
      }finally{
         a += 5;
         //other codes.
      }
      return a;
   }//最终返回值为20

2. Le type de données de référence modifie la valeur de l'objet de référence

   public static StringBuffer test2(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb.append("DEF");
         //other codes.
      }
      return sb;
   }//最终返回中内容为abcDEF
  public static StringBuffer test3(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb = new StringBuffer("DEF");
         //other codes.
      }
      return sb;
   }//最终返回值中的内容为abc

Dans le test de cette situation, il peut On constate que s'il y a une instruction return avant finalement, quelles que soient les modifications apportées à la variable de retour dans finalement, la variable elle-même ne changera pas, par exemple, la réaffectation d'une valeur à une variable de type de base ou la réaffectation d'une référence à une référence. La variable de type ne sera pas enregistrée dans la valeur de retour. Cependant, l'instruction infinally sera exécutée, de sorte que le contenu de l'objet pointé par la variable de type référence infinally puisse être modifié et la modification est effective. Cette situation peut être comprise de cette façon : lorsqu'elle rencontre une instruction return, la machine virtuelle construit une maison pour la valeur de retour. La maison peut-elle être démolie à volonté ? ne peut pas. Mais les gens dans la maison peuvent changer. Les variables des types de données de base et des types de référence eux-mêmes sont des maisons, et le contenu des objets pointés par les variables de type référence sont les personnes dans la maison.

Il existe un si petit test :

   public static int test(int num){
      int a = 10;
      try{
         return a;
      }catch(ArithmeticException e){
         a = 20;
         return a;
      }finally{
         a = 30;
         return a;
      }
   }

1.1 Quelle est la valeur de retour lorsqu'il n'y a pas d'exception dans le bloc try ?

1.2 Quelle est la valeur de retour lorsqu'il y a une ArithmeticException dans le bloc try ?

1.3 Quelle est la valeur de retour lorsqu'il y a d'autres exceptions dans le bloc try ?

Réponse : Tous ont 30. La raison en est qu'après avoir exécuté le code avant le retour dans le bloc try, le jvm insère le code dans le bloc final entre les retours. Le bloc final contient le retour, il renvoie donc. directement.

Recommandations associées :

Ordre d'exécution des instructions try, enfin et return en Java

Exemples de blocs de code en Java Ordre d'exécution

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn