关于Java的两种类型转换:
第一种是强类型转换,第二种是弱类型转换.
每种类型转换都存在着一定的风险,只有清晰地去认识它们,才能够少犯错误
强类型转换
强类型转换出现的有效位数低位数据丢失(将出现逻辑错误)、范围的高位溢出(将出现异常).
这些错误是由程序员负责的,这就需要我们在进行强制类型转换的时候,要多加注意
下面让我们看一下低位丢失和高位溢出的情况
public class demo {
public static void main(String[] args) {
int x;
float y=11111111111.0f;
x = (int)11.1 +(int)22.2; //低位丢失
System.out.println(" "+x);
x = (int)y;
System.out.println(" "+x);
}
}
结果为:
对于低位丢失,应该很好理解,不少朋友也知道高位溢出是怎么回事,就是容量不够了呗,那么解释为什么结果是2147473647却说不太清楚
那么让我们详细看看这是什么情况
我们知道int在任何操作系统上的Java都是4个字节,也就是32位
二进制范围: -2^31 ~ 2^31 – 1
十进制范围: -2147483648 ~ 2147483647
最大十进制有效位数:10(整数部分最多不超过10位,多于10位的数字强制转化为int类型,就会出现高位溢出)
类似的:
byte(1字节) D7----------------D0
采用补码存储
二进制范围: -27 ~ +(27 – 1)
十进制范围: -128 ~ 127
最大十进制有效位数: 3
short(2字节) D15----------------D0
采用补码存储
二进制范围: -215 ~ +(215 – 1)
十进制范围: -32768 ~ 32767
最大十进制有效位数: 5
int(4字节) D31----------------D0
采用补码存储
二进制范围: -231 ~ +(231 – 1)
十进制范围: -2147483648 ~ 2147483647
最大十进制有效位数: 10
long(8字节) D63----------------D0
采用补码存储
二进制范围: -263 ~ +(263 – 1)
十进制范围: -9223772036854775808 ~ 9223772036854775807
最大十进制有效位数: 19
char(2字节) D15----------------D0
采用无符号存储:unsigned short
二进制范围: 0 ~ +(216 – 1)
十进制范围: 0 ~ 64335
最大十进制有效位数: 5
float(4字节) D15----------------D0
采用IEEE754单精度浮点数格式存储
最大二进制有效位数: D23----------------D0
最大十进制有效位数: 8
double(8字节) D63----------------D0
采用IEEE754双精度浮点数格式存储
二进制范围:
最大值为1 x (253 - 1) x 2971
最小为1 x 2-1074
十进制范围:
最大值为±1.7976931348623157 x 10308,
最小为±5 x 10-324
Number.MAX_VALUE:1.7976931348623157 x 10308 (最大表示数,理解为最大值)
Number.MIN_VALUE:5 x 10-324 (最大\小表示数,理解为最小值)
Number.NEGATIVE_INFINITY:-Infinity
Number.POSITIVE_INFINITY:Infinity
Number.NaN:NaN
最大二进制有效位数: D53----------------D0
最大十进制有效位数: 17
隐式类型转换
所谓隐式类型转换就是下图的规则:
高位不会出现溢出,但是可能出现有效位数低位丢失(如下图中的虚线所示),将隐式出现逻辑错误,由程序员负责。
虚线的地方 要多加注意
注意整型(long) 与 float类型 一同运算的时候,要将long类型转换成float类型
上面这张图是我们引入的模型
y 表示最大十进制的位数
x 表示二进制的有效位数
比如说 float类型
尾数位的23位为二进制的有效位数 第32位是符号位,紧挨着的8位是 指数位
对于 int 类型第32位是符号位 其它31位是二进制的有效位数
int 2进制的有效位数 > float 2进制的有效位数
但是 int 最大十进制有效位数 小于 float 最大十进制有效位数 (也就是int 最大值 < float 最大值)
通俗点讲:
拿31位的有效位数字放到23位的有效数字中肯定不行呀
但是要注意的是int 值总的范围大小是2的32次方,而float类型因为有8位指数位,所以要大得多.
建立下面模型:
同理:
隐式类型转换可能出现低位丢失情况:
1、运算表达式
x(int) + y(float)
2、赋值表达式
y(float) = x(int)7
上面介绍过了
开始介绍下面的
3、方法调用,实参到形参的传递
方法定义:f( float y )
方法调用:o.f(x(int) )
举个例子:
//Application.java
class Person {
int ID;
int age;
Person(int ID,int age) {
this.ID = ID;
this.age = age;
}
void intfloat(int x,float y) {
System.out.println("float y =" + y + ",int x=" + x);
}
}
public class Application {
public static void main(String[] args) {
Person p = new Person(1,21);
int x = 12345678;
float y = 0;
System.out.println("------------int,float均在重叠范围---------------");
//1.赋值表达式
//输出:float y = 1.2345678E7,int x = 12345678
y = x;
System.out.println("float y =" + y + ",int x=" + x);
//2.算术运算表达式
//输出:float y = 1.2345678E7,int x = 12345678
y = 0;
y = y + x;
System.out.println("float y =" + y + ",int x=" + x);
//3.方法调用表达式实参到形参的传递
//输出:float y = 1.2345678E7,int x = 12345678
p.intfloat(x,x);
System.out.println("------------int,float不在重叠范围---------------");
x = 123456789;
y = 0;
//1.赋值表达式,出现低位丢失,丢失时的四舍五入
//输出:float y = 1.23456792E8,int x = 123456789
y = x;
System.out.println("float y =" + y + ",int x=" + x);
//2.算术运算表达式,出现低位丢失,丢失时的四舍五入
//输出:float y = 1.23456792E8,int x = 123456789
y = 0;
y = y + x;
System.out.println("float y =" + y + ",int x=" + x);
//3.方法调用表达式实参到形参的传递 ,出现低位丢失,丢失时的四舍五入
//输出:float y = 1.23456792E8,int x = 123456789
p.intfloat(x,x);
}
}
这是结果