boolean占几个字节
老师,今天面试官问我java中,boolean类型占几个字节。我当时没答上来,回去查资料,发现boolean类型没有一个准确的说法,怎么办呢?
答:(文章略长,如果觉得解析过程麻烦,可以直接翻到末尾,看加粗字体的结论)
这种概念性问题,最权威的就是查阅官网资料。Oracle官方已经在官网对基本数据类型,所占的字节数进行了说明,
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
但遗憾的是,官网唯独没有明确说明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.
翻译过来,大致意思就是说:boolean类型的值有两个“真和假”。使用这个类型,可以用于简单的标记真/假的条件。这个类型可以表示一些信息,但它占用的字节大小并没有精确的定义。
显然,官网也没有明确指出boolean类型到底占了几个字节。那怎么办?其实应该高兴。因为现在是互联网时代,并且我们并不是第一批学java的人。所以,只需要做个伸手党,google一下就完事。
那看看google怎么说。
在google中能查到一篇文章(原文地址:https://stackoverflow.com/questions/383551/what-is-the-size-of-a-boolean-variable-in-java)。里面有个高手,通过实操测试了在Sun's JDK build 1.6.0_11环境下,boolean类型到底占几个字节,实操源码如下。
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();
}
}
运行结果:
Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.0
简单计算一下上面的运行结果:用int类型的计算结果Average size(328.0)除以boolean类型的Average size(87.978576),结果是4.069004536942219。从这个结论可以说明,int的长度大致是boolean的4倍,而int是占4个字节。因此可以猜测,boolean类型占1个字节。
继续往下读。在上面那个实操页的下面,还有另一位大神,通过回复提出了一个质疑,回复内容如下
That answer suggests there are significant reasons to use boolean[],
but as the comments there indicate,
there isn't much to back it up. Having said that:
I don't program much in Java (and didn't provide any evidence either ;)
翻译过来,重点是提到了“你的这个实操用的是boolean数组,而不是boolean类型本身,所以结论嘛也并不能准确的用于boolean”。说的好像挺有道理,那boolean到底占几个字节?
实际上,如果你接着google,这个问题还是会得到结论的。但也可以换个方式,看书。这个数据类型问题必然和java虚拟机有关,所以《Java虚拟机规范》一书中,其实也对这个问题进行过说明,以下是本书中相关的两个结论(不是原文,是对原文进行了提炼):
1.JVM没有提供booolean类型专用的字节码指令,而是使用int相关指令来代替。
2.对boolean数组的访问与修改,会共用byte数组的baload和bastore指令。
分析这两个结论,问题就解决了。
(1)上面的第1个结论是说:boolean在底层实际会调用int,那么既然int占4个字节,boolean也自然占4个字节。即,boolean类型占4个字节。
(2)上面的第2个结论是说:boolean数组在底层会用到byte指令,那么既然byte占1个字节,boolean数组中的boolean也就占1个字节。即,boolean数组中的boolean占1个字节。
综上两点,得出最终结论:在符合JVM规范的虚拟机中,
如果boolean是单独使用:boolean占4个字节。
如果boolean是以“boolean数组”的形式使用:boolean占1个字节。
提示:以上结论是《Java虚拟机规范》一书给的,也就是说,仅仅适用于那些遵循了“规范”的JVM。换句话说,如果某个JVM没有遵循规范,boolean到底几个字节就又无法得知了。
- 完 -
推荐阅读