前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在java中boolean类型占多少字节?

在java中boolean类型占多少字节?

作者头像
冬天里的懒猫
发布2020-09-11 06:49:23
2.4K0
发布2020-09-11 06:49:23
举报

近看到一个特别有意思的面试题,就是面试官问boolean占多少字节。一时间还不知道如何回答。我们先来看看java中的基本数据类型。

1.八大基本数据类型

java提供了8大基本数据类型:

数据类型

长度

位数

默认值

byte

1Byte

8

0

short

2Byte

16

0

int

4Byte

32

0

long

8Byte

64

0

float

4Byte

32

0.0f

double

8Byte

64

0.0d

boolean

-

-

false

在一些资料上都有上述介绍。对于其他类型都好理解,唯独对于boolean,长度一直没有很好的说明。我们来看看jvm中是如何实现的。

2.jvm规范描述

首先来看看jvm规范对boolean的描述:

代码语言:javascript
复制
2.3.4 The boolean Type
Although the Java Virtual Machine defines a boolean type, it only provides
very limited support for it. There are no Java Virtual Machine instructions solely
dedicated to operations on boolean values. Instead, expressions in the Java
programming language that operate on boolean values are compiled to use values
of the Java Virtual Machine int data type.
The Java Virtual Machine does directly support boolean arrays. Its newarray
instruction (§newarray) enables creation of boolean arrays. Arrays of type
boolean are accessed and modified using the byte array instructions baload and
bastore (§baload, §bastore).
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.
The Java Virtual Machine encodes boolean array components using 1 to represent
true and 0 to represent false. Where Java programming language boolean values
are mapped by compilers to values of Java Virtual Machine type int, the compilers
must use the same encoding.

大意是说,尽管在java虚拟机中定义了boolean类型,但是对它的支持是很有限的。没有专门针对boolean的java虚拟机指令,相反,java语言中操作boolean的表达式,在编译的时候,会被转换为int类型的值。 java虚拟机直接支持boolean数组,newarray指令允许创建boolean数组,使用字节数据的指令baload和bastore访问和修改boolean类型的数组。 在oracle的java虚拟机中,java语言中的boolean数组被编码为java虚拟机中的字节数组。每个boolean元素使用8位,1个字节来表示。 java虚拟机中使用1表示真,0表示假,来对boolean进行编码。如果编译器将java语言的boolean值映射位虚拟机类型的int类型,则编译器也必须使用相同的编码。

通过上述描述可以看出,实际上,boolean的变量是被当作int类型来处理的,而boolean数组,会被特殊处理。

3.java字节码

我们写一段java代码来进行验证:

代码语言:javascript
复制
package com.dhb.test;

import java.nio.ByteBuffer;

public class BooleanTest {

	public static void main(String[] args) {
		boolean a = false;
		boolean[] array = {true,true,true,true,true};
	}
}

通过javap来查看其字节码:

代码语言:javascript
复制
$ javap -c -l -s -verbose BooleanTest.class
Classfile /D:/workspace-git/MyProject/target/classes/com/dhb/test/BooleanTest.class
  Last modified 2020-9-9; size 477 bytes
  MD5 checksum ae4d3635b02ccda5fe262ef944987b72
  Compiled from "BooleanTest.java"
public class com.dhb.test.BooleanTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#21         // java/lang/Object."<init>":()V
   #2 = Class              #22            // com/dhb/test/BooleanTest
   #3 = Class              #23            // java/lang/Object
   #4 = Utf8               <init>
   #5 = Utf8               ()V
   #6 = Utf8               Code
   #7 = Utf8               LineNumberTable
   #8 = Utf8               LocalVariableTable
   #9 = Utf8               this
  #10 = Utf8               Lcom/dhb/test/BooleanTest;
  #11 = Utf8               main
  #12 = Utf8               ([Ljava/lang/String;)V
  #13 = Utf8               args
  #14 = Utf8               [Ljava/lang/String;
  #15 = Utf8               a
  #16 = Utf8               Z
  #17 = Utf8               array
  #18 = Utf8               [Z
  #19 = Utf8               SourceFile
  #20 = Utf8               BooleanTest.java
  #21 = NameAndType        #4:#5          // "<init>":()V
  #22 = Utf8               com/dhb/test/BooleanTest
  #23 = Utf8               java/lang/Object
{
  public com.dhb.test.BooleanTest();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/dhb/test/BooleanTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: iconst_5
         3: newarray       boolean
         5: dup
         6: iconst_0
         7: iconst_1
         8: bastore
         9: dup
        10: iconst_1
        11: iconst_1
        12: bastore
        13: dup
        14: iconst_2
        15: iconst_1
        16: bastore
        17: dup
        18: iconst_3
        19: iconst_1
        20: bastore
        21: dup
        22: iconst_4
        23: iconst_1
        24: bastore
        25: astore_2
        26: return
      LineNumberTable:
        line 8: 0
        line 9: 2
        line 10: 26
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      27     0  args   [Ljava/lang/String;
            2      25     1     a   Z
           26       1     2 array   [Z
}
SourceFile: "BooleanTest.java"

可以看到,在定义变量 boolean a = false的时候:

代码语言:javascript
复制
     0: iconst_0
     1: istore_1

是将int类型的0压入栈顶。之后将int类型的值,存入第一个int类型的变量中去。我们可以对照本地变量表:

代码语言:javascript
复制
 LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      27     0  args   [Ljava/lang/String;
            2      25     1     a   Z
           26       1     2 array   [Z

slot为1的就是a。那么a=false实际上就是将a=1。 之后再来看对数组的操作:boolean[] array = {true,true,true,true,true};会转换为:

代码语言:javascript
复制
     2: iconst_5
     3: newarray       boolean
     5: dup
     6: iconst_0
     7: iconst_1
     8: bastore
     9: dup
    10: iconst_1
    11: iconst_1
    12: bastore
    13: dup
    14: iconst_2
    15: iconst_1
    16: bastore
    17: dup
    18: iconst_3
    19: iconst_1
    20: bastore
    21: dup
    22: iconst_4
    23: iconst_1
    24: bastore
    25: astore_2

首先是将int 5压入栈顶,之后用这个数字newarray 。之后将iconst_0 和iconst_1 执行bastore。意思就是将数组的第0位将int1设置。之后通过byte数组的方式 bastore到数组中。 实际上可以看出,在字节码中,boolean变量实际上与int等同。而boolean数组的操作,则与操作byte数组等价。

4.代码证明

我们可以用stackOverFlow上的一段代码进行证明,在hotSpot 1.8中,用如下代码证明:

代码语言:javascript
复制
package com.dhb.test;

public class BooleanTest1 {
	private static final int SIZE = 1000000;

	public static void main(String[] args) {
		LotsOfBooleans[] first = new LotsOfBooleans[SIZE];
		LotsOfInts[] second = new LotsOfInts[SIZE];
		System.gc();
		long startMem = getMemory();

		for (int i = 0;i < SIZE; i++) {
			first[i] = new LotsOfBooleans();

		}
		System.gc();
		long endMem = getMemory();

		System.out.println("Size for LotsOfBooleans: " + (endMem - startMem));
		System.out.println("Average size: " + ((endMem - startMem) / ((double) SIZE)));

		System.gc();
		startMem = getMemory();
		for (int i=0; i < SIZE; i++)
		{
			second[i] = new LotsOfInts();
		}
		System.gc();
		endMem = getMemory();

		System.out.println("Size for LotsOfInts: " + (endMem - startMem));
		System.out.println("Average size: " + ((endMem - startMem) / ((double) SIZE)));

		// Make sure nothing gets collected
		long total = 0;
		for (int i=0; i < SIZE; i++)
		{
			total += (first[i].a0 ? 1 : 0) + second[i].a0;
		}
		System.out.println(total);
	}


	private static long getMemory() {
		Runtime runtime = Runtime.getRuntime();
		return runtime.totalMemory() - runtime.freeMemory();
	}


	static class LotsOfBooleans {
		boolean a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
		boolean b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
		boolean c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
		boolean d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
		boolean e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
	}

	static class LotsOfInts {
		int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af;
		int b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf;
		int c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf;
		int d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df;
		int e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef;
	}
}

其执行结果:

代码语言:javascript
复制
Size for LotsOfBooleans: 94654104
Average size: 94.654104
Size for LotsOfInts: 336376256
Average size: 336.376256
0

平均每个boolean数组的大小为94Bit,而boolean数组中有80个boolean,那么每个boolean的长度,不可能超过1个Byte。

5.结论

根据以上描述,可以得出结论: boolean在oracle的jvm中,至少在HotSpot 1.8中,boolean变量的长度为4 Byte。而boolean数组中,每个boolean长度为1 Byte。

由于java不同jvm的实现实际上可能会有不同,以上结论仅限于hotSpot 版本。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 近看到一个特别有意思的面试题,就是面试官问boolean占多少字节。一时间还不知道如何回答。我们先来看看java中的基本数据类型。
  • 1.八大基本数据类型
  • 2.jvm规范描述
  • 3.java字节码
  • 4.代码证明
  • 5.结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档