面试官竟然问我这么简单的题目:Java 中 boolean 占多少字节?我脱出而出......

飞天小牛肉

共 7838字,需浏览 16分钟

 · 2022-07-07


本文收录于 www.cswiki.top


  • 面试官:Java 中 boolean 占多少字节?
  • 我:1 个字节
  • 面试官:emm 你确定吗
  • 我:(开始慌了)确....定.....吧
  • 面试官:好的,那你这边还有什么问题吗?
  • 我:卒......

这种概念性问题,最权威最准确的就是查官网文档

Oracle 官方文档地址在此:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

总共 8 大基础数据类型,其余 7 个都非常明确的标明了占用多少字节,只有 boolean 模棱两可:

boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined.

翻译下划线部分:这个数据类型表示 1 bit 的信息(true or false,编译后用 0 或 1 来表示),但是它的 size 并没有被精确地定义。也就是说,不管它占多大的空间,只有 1 个 bit 的信息是有意义的。

事实上,boolean 到底占用多少大小的空间,“It's virtual machine dependent.”,完全取决于 Java 虚拟机本身的设计

不过显然 boolean 是肯定不可能只占用 1 个 bit 的,最起码也是 1 个 Bytes(字节),因为计算机处理数据的最小单位是 1 个字节

《Java 虚拟机规范》对于 boolean 到底占用多少空间提供了一定的建议(只是建议,具体的实现仍然取决于每个虚拟机是否按照规范来),官方文档在这里:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.3.4

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.

尽管 Java 虚拟机定义了一个布尔类型,但是它只提供了非常有限的支持,并【没有】专门用于对【boolean 值】进行操作的 Java 虚拟机指令。相反,Java 中操作 boolean 值的表达式被编译为使用 int 数据类型的值

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.

不过,Java 虚拟机【直接支持】【boolean 数组】,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baloadbastore 来访问和修改 boolean 数组。

  • newarray 指令:Create new array
  • baload 指令:Load byte or boolean from array
  • bastore 指令:Store into byte or boolean array

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.

在 Oracle 的 Java 虚拟机实现中,Java 中的 boolean 数组被编码为 byte 数组,每个 boolean 元素使用 1 字节(8 bit)


总结下,Java 虚拟机规范提议:

  • 如果 boolean 是 “单独使用”:boolean 被编译为 int 类型,占 4 个字节
  • 如果boolean 是以 “boolean 数组” 的形式使用:boolean 占 1 个字节,Java 虚拟机直接支持 boolean 数组,通过 newarray 指令创建 boolean 数组,然后通过 byte 数组指令 baloadbastore 来访问和修改 boolean 数组

具体还要看虚拟机实现是否按照规范来,所以 boolean 占用 1 个字节、4 个字节都是有可能的

可以通过下述代码来检测下:

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;
}

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;
}


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

    public static void main(String[] args) throws Exception {        
        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();
    }
}

再强调一遍,boolean 占用多少字节取决于虚拟机本身的实现,在 Windows 上 Sun's JDK build 1.6.0_11 的结果如下,这意味着 boolean 值(单独使用)的时候占用 1 个字节:

Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.




心之所向,素履以往,我是小牛肉,小伙伴们下篇文章再见


浏览 58
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报