146 votes

Pourquoi fait changer la variable retournée dans un enfin bloc ne change pas la valeur de retour ?

J’ai une simple classe Java comme indiqué ci-dessous :

Et la sortie de ce code est la suivante :

Pourquoi est ne pas substitué dans le bloc, pourtant contrôler la sortie imprimée ?

165voto

Ted Hopp Points 122617

L' try bloc se termine par l'exécution de l' return déclaration et la valeur de s au moment de l' return exécution d'une instruction est la valeur retournée par la méthode. Le fait que l' finally clause variations ultérieures de la valeur de s (après l' return déclaration complète) n'a pas (à ce point) modifier la valeur de retour.

Remarque que ci-dessus traite de changements de la valeur de s dans la finally bloc, et non pas à l'objet qu' s références. Si s était une référence à un objet mutable ( String ne l'est pas) et le contenu de l'objet ont été modifiées dans la finally bloc, ces modifications de la valeur retournée.

Les règles détaillées pour la façon dont tout cela fonctionne peuvent être trouvés dans la Section 14.20.2 de la Java Language Specification. Notez que l'exécution d'un return relevé de compte comme un arrêt brutal de l' try (bloc de la section de départ "Si l'exécution du bloc try se termine brusquement pour toute autre raison R...." s'applique). Voir la Section 14.17 de la JLS pourquoi un return déclaration est un arrêt brutal d'un bloc.

63voto

Tordek Points 4334

Parce que la valeur de retour est placée sur la pile avant l’appel à enfin.

33voto

Mikhail Points 2585

Si nous regardons à l’intérieur de bytecode, nous remarquerez que JDK a fait une optimisation significative et méthode foo() ressemble à :

Et le bytecode :

Java a conservé « dev » chaîne de le modifier avant de retourner. En fait Voici pas enfin bloc du tout.

22voto

0xCAFEBABE Points 2714

Il y a 2 choses noter ici :

  • Les chaînes sont immuables. Lorsque vous définissez s « substituer la variable s », vous définissez s pour désigner la chaîne Inline, ne changeant pas le tampon char inhérente de l’objet s de changer pour « substituer s variable ».
  • Vous mettez une référence à la s sur la pile pour retourner au code appelant. Par la suite (lorsque le bloc finally s’exécute), modifier la référence ne devrait pas faire quoi que ce soit pour la valeur de retour déjà sur la pile.

13voto

Frank Points 5808

Changer votre code un peu pour prouver la point de Ted.

Comme vous pouvez le voir dans la sortie `` est en effet changé mais après le retour.

Sortie :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X