本文收录于 www.cswiki.top
- 面试官:Java 中 boolean 占多少字节?
- 我:1 个字节
- 面试官:emm 你确定吗
- 我:(开始慌了)确....定.....吧
- 面试官:好的,那你这边还有什么问题吗?
- 我:卒......
这种概念性问题,最权威最准确的就是查官网文档
总共 8 大基础数据类型,其余 7 个都非常明确的标明了占用多少字节,只有 boolean 模棱两可:
boolean: The
boolean
data type has only two possible values:true
andfalse
. 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 到底占用多少空间提供了一定的建议(只是建议,具体的实现仍然取决于每个虚拟机是否按照规范来)
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 onboolean
values. Instead, expressions in the Java programming language that operate onboolean
values are compiled to use values of the Java Virtual Machineint
data type.
尽管 Java 虚拟机定义了一个布尔类型,但是它只提供了非常有限的支持,并【没有】专门用于对【boolean 值】进行操作的 Java 虚拟机指令。相反,Java 中操作 boolean 值的表达式被编译为使用 int 数据类型的值。
The Java Virtual Machine does directly support
boolean
arrays. Itsnewarray
instruction (newarray
) enables creation ofboolean
arrays. Arrays of typeboolean
are accessed and modified using thebyte
array instructionsbaload
andbastore
.
不过,Java 虚拟机【直接支持】【boolean 数组】,通过 newarray
指令创建 boolean 数组,然后通过 byte 数组指令 baload
和 bastore
来访问和修改 boolean 数组。
newarray
指令:Create new arraybaload
指令:Loadbyte
orboolean
from arraybastore
指令:Store intobyte
orboolean
array
In Oracle’s Java Virtual Machine implementation,
boolean
arrays in the Java programming language are encoded as Java Virtual Machinebyte
arrays, using 8 bits perboolean
element.
在 Java 虚拟机实现中,Java 中的 boolean 数组被编码为 byte 数组,每个 boolean 元素使用 1 字节(8 bit)。
总结下,Java 虚拟机规范提议:
- 如果 boolean 是 “单独使用”:boolean 被编译为 int 类型,占 4 个字节
- 如果boolean 是以 “boolean 数组” 的形式使用:boolean 占 1 个字节,Java 虚拟机直接支持 boolean 数组,通过
newarray
指令创建 boolean 数组,然后通过 byte 数组指令baload
和bastore
来访问和修改 boolean 数组
具体还要看虚拟机实现是否按照规范来,所以 boolean 占用 1 个字节、4 个字节都是有可能的
可以通过下述代码来检测下:
代码语言:javascript复制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 个字节:
代码语言:javascript复制Size for LotsOfBooleans: 87978576
Average size: 87.978576
Size for LotsOfInts: 328000000
Average size: 328.
心之所向,素履以往,我是小牛肉,小伙伴们下篇文章再见