我们都知道,Java语言中有个boolean类型。每个boolean类型的变量中存储的是一个true或者是false的逻辑值。那么存储这个逻辑值,需要多大的空间呢?从理论上来讲,存储这个逻辑值只需要1个位(bit)就可以了,很多教科书上谈到这个问题的时候,也说boolean类型的数据在内存中只占1个位。
但是稍微有点计算机常识的人都知道:计算机完成寻址操作的时候,是以字节为最小单位进行的。也就是说每次要读取内存中数据的时候,最小只能精确到1个字节,不能单独读取某个位上的信息。如果boolean类型的变量的值只占1个位,计算机每次读取到1个字节的信息,里面会包含8个boolean变量的值。计算机就不得不通过某种算法去确定这8个值中,哪一个才是我们要找的值。这样做显然非常不合理,因为要完成这个“8选1”的操作又会增加运算工作量。那么Java虚拟机到底是怎样存储boolean值呢?
为了彻底说清楚这个问题,我们还要刨一刨老底。每次JDK出新版本的时候,Java官方都会发布一个对应版本的《虚拟机规范》。在《虚拟机规范》中,对boolean类型的存储有专门的解释,文中说到:“虽然定义了boolean这种数据类型,但是只对它提供了非常有限的支持。在Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达式所操作的boolean值,在编译之后都使用Java虚拟机中的int数据类型来代替,而boolean数组将会被编码成Java虚拟机的byte数组,(因此)每个boolean元素占8位”。
按照这样的说法我们可以得知:boolean类型的数据如果单独使用,占4个字节的空间,而如果存储到boolean数组中,每个元素又只占1个字节。
紧接着问题又来了:单独使用boolean类型数据的时候,为什么要用4个字节来存储呢?用1个或2个字节存储岂不是更节省空间吗?我们必须知道,当下大部分处理器都是32位的(不是操作系统的32位,而是指CPU硬件),把boolean型数据存储成4个字节(32位),存取效率是最高的。
最后还会有小伙伴问:《虚拟机规范》中是这么规定的,但在实现虚拟机的时候,真是按这样的规定来执行吗?为了说清楚这个问题,我们又要科普一个小常识:世界上并非只有Oracle一家公司实现了Java虚拟机(JVM),也有其他厂商或机构会发布自己的Java虚拟机实现。这些厂商或机构在自己的虚拟机中,是否完全按照《规范》的规定来存储boolean型数据就不得而知了。他们会综合考虑运算效率与存储空间两方面的性能。