注意:
为什么 float
占4个字节,而 long
占8个字节,float
表示的范围却比 long
要大得多呢?
原因简单说是因为二者存储的模式不同
long
类型是是直接用 64 位二进制位去存储数据的二进制原码
float
作为浮点数类型,在 java 里遵循IEEE754标准,将 32 位分为 3 个部分,第一部分 1 位存储符号,第二部分 8 位存储浮点数的科学表示后的指数,第三部分23,位存储浮点数的科学表示后的纯小数(有效数字部分),所以浮点数的范围要比其他任何数据类型都要大得多
boolean
类型是否占一位
我们通常默认为boolean
值的长度为1/8字节也就是1位,因为1个二进制位就完全可以表示 ture
和 false
这两个值,但是在实际的内存中,boolean
的占位的大小其实是和 java 的虚拟机有关,毕竟用 java 输出 boolean
类型的值是"true"或者"false"这样的字段,而不是0,或者1
整数默认都是整型,小数默认都是double
型
所以表示 long
型常量时要在后面加L(注意大写,小写容易和1混淆),float
型后面需要加F,注意但是 byte/short
类型没有这样的写法,因为 byte
和 short
可以直接赋值范围类的整数
既然整数默认都是整型的,那为什么 byte b = 127;
不会报错
JVM对常量有优化机制(具体可以看我下一篇文章java常量优化机制),虚拟机编译器是认识常量的,知道 -128~127
是在 byte
的取值,但是一旦超出范围就出错,这也是为什么没有 123b
来表示 byte
,22s
来表示 short
的写法了
byte 和 short 类型赋值给 char 类型为什么会报错
虽然说 byte 占一个字节,short 和 char 占两个字节,但是 char 表示的范围是正数的一部分,没有负数的,和 short、byte 类型之间有交叉但是没有包含,所以转换不了
这个编译为什么会报错:byte a = 127; byte b = -128; byte c = a + b;
因为 a
和 b
都是变量,编译器虽然可以确定 a
和 b
两个变量的值都是 byte
的取值范围,但是由于他们是变量,他们相加的值编译器在编译期间是无从得知的,而且JVM中只有 int、long、float、double
四个数字类型支持,所以比 int
小的加法运算自动转化成 int
的加法运算,结果也是 int
类型,因此,编译器会把 byte
和 byte
相加的值默认提升为 int
进行处理
这个编译为什么会报错:byte a = 10; a = a + 10;
而 byte a = 10; a += 10;
不会报错呢
前者原因跟上条一样,编译器会把 byte
和 byte
相加的值默认提升为 int
进行处理
后者是因为JVM对 +=
运算符做了优化,会默认帮我们进行强转,相当于 a = (byte)(a + 10)
取值范围小的,自动转换为取值范围大的类型
注意:boolean 类型不参与类型转换
例
double d = 10; // 这里会出现类型的自动转换, int 自动转换成了 double 类型
System.out.println(d); // 10.0, 这里看出是做了隐式转换了, 因为如果是 int, 是没有后面的 .0 的
byte b = 10;
int i = b; // 当编译 int i = b; 时, b 隐式转换为 int 类型, 在赋值给 i
int i = 2;
double d = 5.0;
System.out.println(d / i); // 结果为 2.5, 这里会将 i 隐式转换为 double 类型
取值范围大的, 转换成取值范围小的
注意:不推荐使用强制类型转换,因为会损失精度