1/8个字节
理论上来说,只占用1/8个字节,true和false可以用1和0来表示。
1个字节(.class文件中占用容量大小)
在对.java文件编译后,布尔值会占用1个字节的空间来存储。
public class TestClass {
private static boolean m = true;
}
public class TestClass {
private static boolean m = false;
}
以对上面两段代码编译为例,得到的字节码及javap执行结果如下图所示
可以发现0x04和0x03之间的差异,0xb3代表putstatic字节码指令,含义如下图所示,0x0002即常量池中的字段描述符对应的索引(描述符如上图所示(但不限于此),其中m是字段名,Z即boolean类型)
ps:实例成员也会得到类似结果
4个字节(.class文件中占用容量大小)
public class TestClass {
private static final boolean m = true;
}
public class TestClass {
private static final boolean m = false;
}
以对上面两段代码编译为例,得到的字节码如下图所示
可以发现0x00000001和0x00000000之间的差异
造成1个字节与4个字节存储大小的差异是由初始化的方式导致的。
目前Oracle公司实现的Javac编译器的选择是,如果同时使用final和static来修饰一个变量(按照习惯,这里称“常量”更贴切),并且这个变量的数据类型是基本类型或者java.lang.String的话,就将会生成ConstantValue属性来进行初始化;如果这个变量没有被final修饰,或者并非基本类型及字符串,则将会选择在<clinit>()方法中进行初始化。
<clinit>()方法指的就是类构造器方法。
ConstantValue属性可以理解为字节码的一部分的含义,下图为其结构与解读
可以看到ConstantValue对应的值的索引为7,那么索引为7的常量值(类型为CONSTANT_Integer_info),它的容量大小是多少呢,通过查表可得,为4个字节
u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
4个字节(编译期或运行期)
在Java虚拟机的指令集中,大多数指令都包含其操作所对应的数据类型信息。举个例子,iload指令用于从局部变量表中加载int型的数据到操作数栈中,而fload指令加载的则是float类型的数据。
并非每种数据类型和每一种操作都有对应的指令。
大部分指令都没有支持整数类型byte、char和short,甚至没有任何指令支持boolean类型。编译器会在编译期或运行期将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。
持续学习中……
该文章是基于《深入理解java虚拟机》的一些理解与实践,如有错误还请各位大佬多多包涵指正。