Java的基本数据类型
类型 | 意义 | 取值 |
---|---|---|
boolean | 布尔值 | true或false |
byte | 8位有符号整型 | -128~127 |
short | 16位有符号整型 | -pow(2,15)~pow(2,15)-1 |
int | 32位有符号整型 | -pow(2,31)~pow(2,31)-1 |
long | 64位有符号整型 | -pow(2,63)~pow(2,63)-1 |
float | 32位浮点数 | IEEE754标准单精度浮点数 |
double | 64位浮点数 | IEEE754标准双精度浮点数 |
char | 字符型 | 16位不带符号,Unicode字符 |
JVM本地对应的类型
typedef unsigned char jboolean;
typedef signed char jbyte;
typedef short jshort;
typedef int jint;
typedef long long jlong;
或
typedef __int64 jlong;
typedef double jdouble;
typedef float jfloat;
typedef unsigned short jchar;
java的boolean在jvm中对应unsigned char类型(0为false而非0为true);byte对应signed char类型;short对应short类型;int对应int类型;long对应long long或者_int64类型;double对应double类型;float对应float类型;char对应unsigned short类型。
编译器生成bytecode的类型
compiler将java编译为class,而class文件除了结构信息和元数据等,还包含了bytecode,这其实就是虚拟机的指令,好比物理机的机器指令。举个例子,
public int getInt(){
int a = 100;
return a;
}
生成该方法的bytecode为
bipush 100
istore_1
iload_1
ireturn
bipush 100
将100以byte型推进operand stack中,istore_1
将operand stack顶int型数值存入第二个局部变量,iload_1
将第二个int型局部变量推进operand stack,ireturn
返回int。
对于一些toy jvm会简单地直接用C/C++处理指令,但对于工业级的openjdk中的Hotspot则会继续生成汇编指令执行。
从上面的情况可以看到java的int型编译成bytecode后可能会变成byte型来表示,这个主要取决于java的int型数值的大小,编译器会在编译期间判断大小从而生成对应的指令,比如小于128时则为bipush
,大于138且小于32768时则为sipush
,它表示以short型表示,而大于32768的则都是用ldc+常量池来表示。
执行时的类型
在指令执行时JVM并不需要指明类型,因为指令已经包含了类型信息,但由于bytecode指令只用1个字节来表示,所以指令数量需要控制,并不是每种基础数据类型都有对应的操作指令,比如iload
lload
fload
dload
对应int
long
float
and
double
。类似还有ireturn
lreturn
freturn
dreturn
。
所以执行引擎只要根据不同的指令做不同的类型处理即可。
Java调本地
如果某个java对象调用了native方法,此本地方法由编译器编译后access flags 会生成ACC_NATIVE
标识,执行引擎执行bytecode时,根据java-jvm类型的映射也可能会涉及到类型处理。
====广告时间,可直接跳过====
鄙人的新书《Tomcat内核设计剖析》已经在京东预售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。
=========================
欢迎关注: