自动类型转换
将取值范围小的类型,自动提升为取值范围大的类型。
数据范围与字节数不一定相关,如float数据范围比long更加广泛,但float是4个字节,而long是8个字节。
Byte、short、char-->int-->long-->float-->double
强制类型转换
将取值范围大的类型,强制转换成取值范围小的类型。
转换格式:数据类型 变量名 = (数据类型)被转数据值;
注意
- 浮点转成整数,直接取消小数点,可能造成数据损失精度。
- int 强制转成 short 砍掉2个字节,可能造成数据丢失(溢出)。
- Byte/short/char在运算时,都会被首先提升为int类型,在进行计算
- 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte)(short)(char).
1.如果没有超过左侧的范围,编译器补上强转。
2.如果右侧超过了左侧范围,那么直接编译器报错。这里是引用
- 隐含有强制转换。 short s = 1; s+=1;
分析: s += 1 逻辑上看作是 s = s + 1 计算结果被提升为int类型,再向short类型赋值时发生错误,因为不能将取值范围 大的类型赋值到取值范围小的类型。但是, s=s+1进行两次运算 , += 是一个运算符,只运算一次,并带有强制转换的特点, 也就是说 s += 1 就是 s = (short)(s + 1) ,因此程序没有问题编译通过,运行结果是2。不是+1,就是+12345也能通过,虽然有数据溢出。这里是引用
- byte b1=1; byte b2=2; byte b3=1 + 2; byte b4=b1 + b2;
分析:b3 = 1 + 2,1 和 2 是常量,为固定不变的数据,在编译的时候(编译器javac),已经确定了 1+2的结果并没有超过byte类型的取值范围,可以赋值给变量 b3,因此 b3=1 + 2是正确的。(超过了就会报错,编译失败)。称为编译器的常量优化。 反之,b4 = b2 + b3,b2和b3是变量,变量的值是可能变化的,在编译的时候,编译器javac不确定b2+b3的结果是什么,因此会将结果以int类型进行处理,所以int类型不能赋值给byte类型,因此编译失败。