字节长度 | 位长度 | 整数型 | 非整数型 |
---|---|---|---|
1 | 8 | byte(字节型) | boolean(布尔型) |
2 | 16 | short(短整型) | char(字符型) |
4 | 32 | int(整型) | float(单精度浮点型) |
8 | 64 | long(长整型) | double(双精度浮点型) |
其中,整数型的数值运算默认是以int
类型进行运算的,浮点型的数值运算默认是以double
类型进行运算的。
我们用jshell来测试一下:
jshell> short foo = 1 // 定义一个short型变量
foo ==> 1
jshell> foo = foo + 1 // short变量+1(这里的1是int类型)
| Error:
| incompatible types: possible lossy conversion from int to short // 提示错误:从int到short的转换可能会有损
| foo = foo + 1
| ^-----^
jshell> float bar = 1 // 定义一个float型变量
bar ==> 1.0
jshell> bar = bar + 1.0 // float变量+1.0(这里的1.0是double类型)
| Error:
| incompatible types: possible lossy conversion from double to float // 提示错误:从double到float的转换可能会有损
| bar = bar + 1.0
| ^-------^
jshell> foo += 1 // foo执行自增1可以执行,这是因为foo += 1相当于foo = (short)(foo + 1)
$7 ==> 2
jshell> bar += 1.0 // bar执行自增1.0可以执行,这是因为bar += 1相当于bar = (float)(bar + 1.0)
$8 ==> 2.0
jshell> foo = (short)(foo + 1) // 自增操作会隐含强制类型转换,将高位的int转换成低位的short
foo ==> 3
jshell> bar = (float)(bar + 1.0) // 自增操作会隐含强制类型转换,将高位的double转换成低位的float
bar ==> 3.0
所以我们就可以得出结论,低位的数据类型在进行运算操作时会自动转换成高位吗?
我们再看一个jshell实例
jshell> byte f1 = 1
f1 ==> 1
jshell> byte f2 = 1
f2 ==> 1
jshell> byte f3
f3 ==> 0
jshell> f3 = f1 + f2
| Error:
| incompatible types: possible lossy conversion from int to byte // 提示错误:从int到byte的转换可能会有损
| f3 = f1 + f2
| ^-----^
jshell> char c1 = '1'
c1 ==> '1'
jshell> char c2 = '2'
c2 ==> '2'
jshell> char c3
c3 ==> ''
jshell> c3 = c1 + c2
| Error:
| incompatible types: possible lossy conversion from int to char // 提示错误:从int到char的转换可能会有损
| c3 = c1 + c2
| ^-----^
jshell> float b1 = 1.0f
b1 ==> 1.0
jshell> float b2 = 1.0f
b2 ==> 1.0
jshell> float b3
b3 ==> 0.0
jshell> b3 = b1 + b2 // 两个float变量相加没有提示错误
b3 ==> 2.0
结论
由此我们可以看出,在整数型和char
中,对于位数小于int
的byte
、short
、char
进行运算操作时会有变量提升,自动转换成32位的int
类型。而与int
同为32位的float
类型在进行运算时则不会有变量提升。
根本原因
JVM与Java语言设计时的设定如此。
- 虚拟机本身也是个机器,在内存运用上选择了32bit的标准,对于位数小于
int
的byte
、short
、char
直接转成int
来运算- 字节码的设计更加简洁,从计算的角度看提升了性能,在数值运算的扩张上也预留了空间,不必到时候再手动扩,假如JVM将byte这种类型加入到运算过程就需要更多的晶体管,对完善算术逻辑单元无用
- 虚拟机运行在32bit系统上,如此更易于实现底层机制
- 小的数据类型在数组中有所优势,会占用更少的字节,但运算中并无类似的优势