问题
基础类型范围如何限制以及在内存中的大小?
Primitive Types
类型 | 默认值 | 包装类 | 虚拟机内部符号 |
---|---|---|---|
boolean | false | Boolean | Z |
byte | 0 | Byte | B |
short | 0 | Short | S |
char | \u0000 | Character | C |
int | 0 | Integer | I |
long | 0L | Long | J |
float | +0.0F | Float | F |
double | +0.0D | Double | D |
范围限制
如何来查看 Primitive Types 的类型限制大小呢? 在此我们需要使用到一个工具: jol.
Maven 引入:
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
代码:
public class Main {
public static void main(String[] args) {
Byte b = 0;
ClassLayout bcl = ClassLayout.parseInstance(b);
System.out.println(bcl.toPrintable());
Integer i = 0;
ClassLayout icl = ClassLayout.parseInstance(i);
System.out.println(icl.toPrintable());
}
}
根据打印我们可以知道 Primitive Types 在实例中的内存大小, byte
占 1 个字节, int
占 4 个字节.
那这个限制是在哪里判断的呢?
编译上面代码我们发现, 原来 Primitive Types 的限制是由 javac
编译时判断的, 超过范围且未进行强转则报错.
JVM
局部变量
在 JVM 中, 方法相当于一个个栈帧(StackFrame), 而局部变量则是存储在栈帧的局部变量表(LocalVariableTable)里, 所以要看 Primitive Types 的内存大小, 需要查看 JVM 是如何操作这些栈变量的内存的
public class Main {
public static void main(String[] args) {
byte b = 0;
short s = 0;
int i = 0;
long l = 0L;
}
}
查看 main 方法相关字节码
0 iconst_0
1 istore_1
2 iconst_0
3 istore_2
4 iconst_0
5 istore_3
6 lconst_0
7 lstore 4
9 return
istore
istore 字节码将栈里的 byte
、short
和 int
存储到对应的局部变量表里去, 所以它们占用的内存大小是一致的, 一个 slot 位置.
lstore
lstore 字节码将栈里 long
存储到对应的局部变量表里去, 但占两个位置.