Taille d'octet de type booléen dans JavaVM

Ce que je veux dire

En Java, ** les variables de type booléen ne font pas 1 octet! (Conclusion) **

... peut être. (Boso Vérifions-le.

Donnez-moi juste la conclusion! La personne qui dit Veuillez passer à «à la fin».

environnement

Taille booléenne en tant que variable locale

Écrivez le code suivant:

Sandbox.java


public class Sandbox{
    public static void main(String[] args){
        boolean b = true;
        //En raison de l'attribut StackMapTable
        if(b){
            b=true;
        }
    }
}

Compilez ceci comme d'habitude et regardez le contenu du fichier de sortie ".class".

> javac Sandbox.java
> javap -v Sandbox

(Omission)

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_1
         1: istore_1
         2: iload_1
         3: ifeq          8
         6: iconst_1
         7: istore_1
         8: return
      LineNumberTable:
        line 3: 0
        line 4: 2
        line 5: 6
        line 7: 8
      StackMapTable: number_of_entries = 1
        frame_type = 252 /* append */
          offset_delta = 8
          locals = [ int ]
}
SourceFile: "Sandbox.java"

cette

locals = [ int ]

Veuillez faire attention à. Cela signifie que la variable locale est int. (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.7.4)

En d'autres termes

** Les variables de type booléen en tant que variables locales sont converties en variables de type int **

à propos de ça.

Boolean comme champ de classe

À propos du type

Écrivez le code suivant.

Sandbox.java


public class Sandbox{
    boolean b;
    public static void main(String[] args){
    }
}

Faites la même chose qu'avant:

> javac Sandbox.java
> javap -v Sandbox

(Omission)
{
  boolean b;
    descriptor: Z
    flags: (0x0000)

(Omission)
}
SourceFile: "Sandbox.java"

cette

descriptor: Z

Autrement dit, "le type est booléen". (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.3.2)

Alors

** Les variables de type booléen en tant que champs de classe sont traitées comme des variables de type booléen **

La chose a été montrée. (Bien sûr)

Taille d'octet booléenne en tant que champ de classe

Alors, quelle est la taille de cette variable? Écrivez le code suivant:

Sandbox.java


public class Sandbox{
    static int i;
    static boolean b;
    public static void main(String[] args){
       b=true;
       i=0x111111;
    }
}

Commencez par compiler ceci.

> javac Sandbox.java

** Ouvrez le fichier de sortie ".class" avec un éditeur binaire et ** Trouvez la séquence d'octets B3 00 0E et réécrivez-la comme B3 00 07. C'est, image.png cette image.png Je vais le faire.

Remarque: il peut y avoir 0E en plus de la colonne B3 00 0E, mais ne la réécrivez pas.

Ensuite, regardez le contenu avec javap.

> javap -v Sandbox
(...Omission)

    Code:
      stack=1, locals=1, args_size=1
         0: iconst_1
         1: putstatic     #7                  // Field b:Z
         4: ldc           #13                 // int 1118481
         6: putstatic     #7                  // Field b:Z
         9: return

(Omission...)

Si cela se produit, vous réussissez.

Remarque: Cette opération est réécrite pour attribuer un numéro à la variable b au lieu d'attribuer un numéro à la variable i.

Exécutez cette version modifiée ".class".

> java Sandbox

Le fait que rien ne soit affiché a réussi. En d'autres termes, vous pouvez affecter 3 octets de données à la variable booléenne,

** Les champs de classe de type booléen peuvent être utilisés de la même manière que les variables de type int **

à propos de ça. (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-2.html#jvms-2.11.1)

À propos du tableau booléen

Type de tableau booléen

Écrivez le code suivant.

Sandbox.java


public class Sandbox{
   
   static boolean b[];
   
   public static void main(String[] args){
       boolean[] lb = new boolean[]{true};
       //En raison de l'attribut StackMapTable
       if(lb[0]){
           b[0]=true;
       }
   }
}

Compilez-le et regardez le contenu.

>javac Sandbox.java

>javap -v Sandbox 

(...Omission)
{
  static boolean[] b;
    descriptor: [Z
    flags: (0x0008) ACC_STATIC

(...Omission...)

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=2, args_size=1
         0: iconst_1
         1: newarray       boolean
         3: dup
         4: iconst_0
         5: iconst_1
         6: bastore
         7: astore_1
         8: aload_1
         9: iconst_0
        10: baload
        11: ifeq          20
        14: getstatic     #7                  // Field b:[Z
        17: iconst_0
        18: iconst_1
        19: bastore
        20: return
      LineNumberTable:
        line 6: 0
        line 8: 8
        line 9: 14
        line 11: 20
      StackMapTable: number_of_entries = 1
        frame_type = 252 /* append */
          offset_delta = 20
          locals = [ class "[Z" ]
}
SourceFile: "Sandbox.java"

Comme avant

static boolean[] b; descriptor: [Z

Signifie que "b est un tableau booléen de type". Aussi,

locals = [ class "[Z" ]

Signifie que le type de variable locale est un tableau booléen. Donc,

** Les variables de type tableau booléen sont traitées comme des variables de type tableau booléen, non limitées aux variables locales et aux champs de classe **

La chose a été montrée.

boolean La taille "un élément" du tableau

(https://docs.oracle.com/javase/specs/jvms) car le tableau booléen lui-même est équivalent à une instance régulière, et il est évident qu'il garantira la taille équivalente (uniquement pour les variables). /se14/html/jvms-2.html#jvms-2.11.5)

Examinez la taille d'un élément. Cependant, c'était la réponse. (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-2.html#jvms-2.3.4)

In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.

C'est,

** Dans l'implémentation Oracle, 8 bits (= 1 octet) sont utilisés pour un élément **

à propos de ça.

À la fin

Je n'ai pas lu une grande partie de la documentation, alors faites-moi savoir s'il y a des erreurs. Ce qui suit est un bonus.

Édition supplémentaire

À propos, la variable b utilisée précédemment dans l'enquête de terrain de classe Utilisation de java / lang / System.out et java / io / PrintStream.println: (I) V Quand j'essaye de le sortir, c'est 1. (Notez que l'argument est int).

>javap -v Sandbox
(...Omission)
  static boolean b;
    descriptor: Z
    flags: (0x0008) ACC_STATIC

(...Omission...)
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: iconst_1
         1: putstatic     #7                  // Field b:Z
         4: ldc           #13                 // int 1118481
         6: putstatic     #7                  // Field b:Z
         9: getstatic     #18                 // Field java/lang/System.out:Ljava/io/PrintStream;
        12: getstatic     #7                  // Field b:Z
        15: invokevirtual #24                 // Method java/io/PrintStream.println:(I)V
        18: return
(Omission...)

>java Sandbox
1

Selon la documentation putstatic (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-6.html#jvms-6.5.putstatic)

If the value is of type int and the field descriptor type is boolean, then the int value is narrowed by taking the bitwise AND of value and 1, resulting in value'.

Il y a. Par conséquent, il semble que le contenu du champ de classe booléenne soit garanti 0 ou 1. putfield · [bastore](https://docs.oracle.com /javase/specs/jvms/se14/html/jvms-6.html#jvms-6.5.bastore) était le même.

C'est pourquoi je ne peux pas dire la taille du booléen. Puisque 0 ou 1 est garanti, la taille réelle de la variable ne doit pas nécessairement être la même que int. J'ai cherché dans la documentation mais je n'ai trouvé aucune description de ce type. Quelqu'un peut-il me dire qui le connaît? (Viens ici et lance)

c'est tout.

Recommended Posts

Taille d'octet de type booléen dans JavaVM
Utilisation du type booléen Rails
Mesurer la taille d'un dossier avec Java
Détermination de type en Java
Types de variables dans ruby
Sortie en multiples de 3