Byte-Größe vom Booleschen Typ in JavaVM

Was ich sagen will

In Java sind ** boolesche Variablen nicht 1 Byte! (Fazit) **

... vielleicht. (Boso Lass es uns überprüfen.

Gib mir einfach die Schlussfolgerung! Die Person, die sagt Bitte fahren Sie mit "am Ende" fort.

Umgebung

Boolesche Größe als lokale Variable

Schreiben Sie den folgenden Code:

Sandbox.java


public class Sandbox{
    public static void main(String[] args){
        boolean b = true;
        //Wegen des StackMapTable-Attributs
        if(b){
            b=true;
        }
    }
}

Kompilieren Sie dies wie gewohnt und sehen Sie sich den Inhalt der Ausgabedatei ".class" an.

> javac Sandbox.java
> javap -v Sandbox

(Unterlassung)

  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"

Dies

locals = [ int ]

Achten Sie bitte auf. Dies bedeutet, dass die lokale Variable int ist. (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.7.4)

Mit anderen Worten

** Boolesche Typvariablen als lokale Variablen werden in int-Typvariablen konvertiert **

darüber.

Boolescher Wert als Klassenfeld

Über den Typ

Schreiben Sie den folgenden Code.

Sandbox.java


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

Machen Sie dasselbe wie zuvor:

> javac Sandbox.java
> javap -v Sandbox

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

(Unterlassung)
}
SourceFile: "Sandbox.java"

Dies

descriptor: Z

Das heißt, "der Typ ist boolesch". (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.3.2)

Damit

** Boolesche Typvariablen als Klassenfelder werden als boolesche Typvariablen behandelt **

Das Ding wurde gezeigt. (Natürlich)

Boolesche Bytegröße als Klassenfeld

Wie groß ist diese Variable? Schreiben Sie den folgenden Code:

Sandbox.java


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

Kompilieren Sie dies zunächst.

> javac Sandbox.java

** Öffnen Sie die Ausgabedatei ".class" mit einem Binäreditor und ** Suchen Sie die Folge der Bytes B3 00 0E und schreiben Sie sie als B3 00 07 um. Das ist, image.png Dies image.png Ich werde dies tun.

Hinweis: Zusätzlich zur Spalte B3 00 0E kann 0E vorhanden sein, aber schreiben Sie diese nicht neu.

Dann schauen Sie sich den Inhalt mit Javap an.

> javap -v Sandbox
(...Unterlassung)

    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

(Unterlassung...)

In diesem Fall sind Sie erfolgreich.

Hinweis: Diese Operation wird neu geschrieben, um der Variablen b eine Nummer zuzuweisen, anstatt der Variablen i eine Nummer zuzuweisen.

Führen Sie diese geänderte Version ".class" aus.

> java Sandbox

Die Tatsache, dass nichts angezeigt wurde, war erfolgreich. Mit anderen Worten, Sie können der booleschen Variablen 3 Datenbytes zuweisen.

** Boolesche Typklassenfelder können auf die gleiche Weise wie int-Typvariablen betrieben werden **

darüber. (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-2.html#jvms-2.11.1)

Über boolesches Array

Boolescher Array-Typ

Schreiben Sie den folgenden Code.

Sandbox.java


public class Sandbox{
   
   static boolean b[];
   
   public static void main(String[] args){
       boolean[] lb = new boolean[]{true};
       //Wegen des StackMapTable-Attributs
       if(lb[0]){
           b[0]=true;
       }
   }
}

Kompilieren Sie dies und sehen Sie sich den Inhalt an.

>javac Sandbox.java

>javap -v Sandbox 

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

(...Unterlassung...)

  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"

Wie vorher

static boolean[] b; descriptor: [Z

Bedeutet, dass "b ein boolesches Array vom Typ ist". Ebenfalls,

locals = [ class "[Z" ]

Bedeutet, dass der lokale Variablentyp ein boolesches Array ist. Deshalb,

** Boolesche Array-Typvariablen werden als boolesche Array-Typvariablen behandelt, nicht beschränkt auf lokale Variablen und Klassenfelder **

Das Ding wurde gezeigt.

boolean Die Größe des Arrays "ein Element"

(https://docs.oracle.com/javase/specs/jvms), da das boolesche Array selbst einer regulären Instanz entspricht und es offensichtlich ist, dass es die entsprechende Größe sicherstellt (nur für Variablen). /se14/html/jvms-2.html#jvms-2.11.5)

Untersuchen Sie die Größe eines Elements. Dies war jedoch die Antwort. (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.

Das ist,

** In der Oracle-Implementierung werden 8 Bits (= 1 Byte) für ein Element verwendet **

darüber.

Am Ende

Ich habe nicht viel von der Dokumentation gelesen. Bitte lassen Sie mich wissen, wenn Fehler vorliegen. Das Folgende ist ein Bonus.

Sonderedition

Übrigens ist die Variable b, die früher in der Klassenfeldumfrage verwendet wurde Verwenden von java / lang / System.out und java / io / PrintStream.println: (I) V. Wenn ich versuche, es auszugeben, ist es 1. (Beachten Sie, dass das Argument int ist).

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

(...Unterlassung...)
  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
(Unterlassung...)

>java Sandbox
1

Laut der putstatischen Dokumentation (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'.

Es gibt. Daher scheint der Inhalt des Feldes der Booleschen Klasse garantiert 0 oder 1 zu sein. putfield · [bastore](https://docs.oracle.com /javase/specs/jvms/se14/html/jvms-6.html#jvms-6.5.bastore) war dasselbe.

Deshalb konnte ich die Größe des Booleschen Werts nicht sagen. Da 0 oder 1 garantiert ist, muss die tatsächliche Variablengröße nicht mit int identisch sein. Ich habe die Dokumentation durchsucht, aber keine solche Beschreibung gefunden. Kann mir bitte jemand sagen, wer damit vertraut ist? (Komm her und wirf)

das ist alles.

Recommended Posts

Byte-Größe vom Booleschen Typ in JavaVM
Verwendung des booleschen Rails-Typs
Messen Sie die Größe eines Ordners mit Java
Typbestimmung in Java
Arten von Variablen in Ruby
Ausgabe in Vielfachen von 3