数据过大和溢出
当要表示的数据超出数据类型的临界范围时,称为溢出。
溢出情况发生时程序并没有做数据范围检查处理,此时会出现数据紊乱情况。
public class OverflowDemo {
public static void main(String[] args) {
//当要表示的数据超出数据类型的临界范围时,称为溢出
//int类型的最大值:0x7fffffff ,因为int是32位的,最高位是符号位,0表示正数
int intMax = 0x7fffffff;
intMax = intMax + 1;//编译只检查语法,不报错
System.out.println(intMax);//-2147483648
int intMin = 0x80000000;
intMin = intMin - 1;
System.out.println(intMin);//2147483647
}
}
自动类型转换,也称为“隐式类型转换:
当把小数据范围类型的数值或变量赋给另一个大数据范围类型变量,系统可以完成自动类型转型.
注意:boolean 类型是不可以转换为其他数据类型。
强制类型转换,也称为“显示类型转换:
当把大范围类型的数值或变量赋给另一个小范围类型变量时,此时系统不能自动完成转换,需要加上强制转换符,但这样的操作可能造成数据精度的降低或溢出,所以使用时要格外注意。
//类型转换演示
public class TypeConversionDemo {
public static void main(String[] args) {
//自动类型转换(隐式类型转换):小转大
byte b = 1;
int a = b;
System.out.println(a);//1
//强制类型转换 : 大转小,可能会造成数据丢失
double d = 3.14;
//强制类型转换通过截断小数部分将浮点数转换为整型
int i = (int) d;
System.out.println(i);//3
//如果将一种类型数值强转为另一种类型,而又超过了目标类型表示的范围,就会产生完全不同数值
byte c = (byte) 300;
System.out.println(c);//44
/*结果分析:
300 = 0b 0000_0000_0000_0000_0000_0001_0010_1100 ; 32位的int类型
而byte类型占1个字节,8位,使用取后8位,得到 c =0b0010_1100 = 44;
*/
}
}
表达式类型的自动提升
当一个算术表达式中包含多个基本数据类型(boolean除外)的值时,整个算术表达式的数据类型将在数据运算时出现类型自动提升.
类型自动提升规则:所有的byte、short、char类型被自动提升到int类型,
整个表达式的最终结果类型被提升到表达式中类型最高的类型
//表达式类型自动提升,,符合自动类型提升的规则
public class AutoDemo {
public static void main(String[] args) {
//表达式的类型会自动提升,其规则是: byte,short,char自动提升为int类型
//整个表达式的最终结果类型被提升到表达式中类型最高的类型
double d = 1 + 'A' + 3.14F;
System.out.println(d);//69.13999938964844
System.out.println('a' + 1);//98
byte b = 22;
//b = b + 11;//编译出错,此时结果类型应该是int
}
}
为什么byte c = 5这是符合强转类型转换条件的,可为什么没转呢?
因为byte类型占1个字节,所表示的范围是[-128,127],编译器发现,5在这个范围之内,所以底层默默的进行了转化.
//byte类型的注意点
public class IntToByteDemo {
public static void main(String[] args) {
byte b1 = 12;
/*
编译通过.但是,默认情况下,一个整型的字面量默认是int类型.所以12其实是int类型
但是,编译器发现,12符合byte类型的范围,所有底层默默的转换了
--------------------------------------------------
byte b2 = 128;编译报错 Type mismatch: cannot convert from int to byte
128超出了byte的范围,此时需要强转
*/
byte b2 = (byte) 250;
/*128 = 0b1111_1010;byte最大值为0b0111_1111 = 127
把最高位1,看做符号位,所以0b1111_1010是一个负数的补码,求该负数, 取反(但符号位除外),+1
得0b1000_0110 = -6
*/
System.out.println(b1);//12
System.out.println(b2);//-6
}
}