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é :
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!