Question

En Java c'est le cas:

public void method() {
  if (condition) {
    Object x = ....;
  }
  System.out.println(x); // Error: x unavailable
}

Ce que je me demande est la suivante: Est-ce le fait que x est limitée à la portée de la if-déclaration juste une caractéristique du compilateur Java, ou est x effectivement retiré de la pile après la if-instruction

Était-ce utile?

La solution

Non, les blocs de code ne reçoivent pas un cadre de pile séparée, l'utilisation d'une de la méthode environnante.

Cependant, une fois la portée des feuilles de variables, il sa place dans le cadre de la pile actuelle peut être réutilisée pour d'autres variables.

La structure et l'utilisation d'un cadre de pile est décrite dans le Java Virtual machine Spécification § 3.6 Cadres de:

  

Une nouvelle trame est créée chaque fois qu'une méthode est appelée. Une trame est détruite lors de ses achève d'invocation de méthode, si cette réalisation est normal ou brusque (il déclenche une exception non traitée).

Ceci indique certainement un 1: 1. Relation entre les invocations de méthodes et cadres

Autres conseils

Les blocs font partie du langage Java (qui est un langage de programmation structuré ) alors qu'ils ne font pas partie du bytecode compilé (qui est un non structuré langue ).

Une spécification de méthode dans un fichier spécifie classe nombre de variables locales les utilisations de la méthode au total, au-dessus de la liste réelle des instructions. Mais où les blocs une fois où dans le code Java ne peuvent pas être déduites du bytecode.

Tout d'abord, dans les variables de bytecode sont stockés dans les emplacements variables et des fentes variables et non pas sur la pile. La fente peut être réutilisé par une autre variable, mais il est pas garanti que la valeur serait retirée de la fente variable.

Par exemple, la classe suivante

  public class A {
    public void method(boolean condition) {
 6    if (condition) {
 7      Object x = "";
 8      System.out.println(x);
 9    }
10    System.out.println(condition);
    }
  }

est compilé dans ce bytecode:

// class version 50.0 (50)
public class A {
  ...

  // access flags 0x1
  public method(Z)V
   L0
    LINENUMBER 6 L0
    ILOAD 1
    IFEQ L1
   L2
    LINENUMBER 7 L2
    LDC ""
    ASTORE 2
   L3
    LINENUMBER 8 L3
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 2
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
   L1
    LINENUMBER 10 L1
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ILOAD 1
    INVOKEVIRTUAL java/io/PrintStream.println (Z)V
   L4
    LINENUMBER 11 L4
    RETURN
   L5
    LOCALVARIABLE this LA; L0 L5 0
    LOCALVARIABLE condition Z L0 L5 1
    LOCALVARIABLE x Ljava/lang/Object; L3 L1 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

Notez que la variable x créée à la ligne 7 est stockée dans l'emplacement de la variable 2, qui est encore disponible pour le pseudo-code correspondant à la ligne 10.

Il n'y a aucune spécification sur la façon dont le langage Java doivent être compilés dans le bytecode autres que quelques exemples comment compiler correctement certaines constructions linguistiques. Cependant compilateur Java est autorisé à éliminer les variables inutilisées. Par exemple. si x ont été attribués, mais pas utilisé partout, le compilateur est autorisé à déposer ce code. De même, le compilateur est inline toutes les constantes statiques.

Oui, il est vraiment retiré de la pile faisant la fente précédemment occupé par « x » réutilisable par une autre variable locale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top