在Java中,进行运算的数据,必须是同一个类型的,如果不是同一类型,将会进行转换。
先把java数据类型和取值范围贴上:
-
自动转换:
将 【取值范围小的类型】 自动提升为 【取值范围大的类型】
①特点;代码不需要进行特殊处理,自动完成
②规则:数据范围从小到大
例如下面的代码:public class DataAutoChange { public static void main(String[] args) { long num1 = 10; // 左边long类型,右边是int类型,符合隐式转换规则 System.out.println(num1); double num2 = 2.5F; // 左边是double类型,右边是float类型,符合隐式转换规则 System.out.println(num2); float num3 = 10L; // 左边是float类型,右边是long类型,符合隐式转换规则 System.out.println(num3); } }
执行结果如下:
-
强制转换:
将 【取值范围大的类型】 强制转换成 【取值范围小的类型 】
①特点:代码需要进行特殊的处理
②规则:范围小的类型 范围小的变量名 = (范围小的类型) 原本范围大的数据;
例1:public class DataAutoChange { public static void main(String[] args) { // int num1 = 10L; // 左边int类型,右边是long类型,编译时,会出现错误提示【从long转换到int可能会有损失】 int num1 = (int) 10L; // 这里进行强制转换操作,就没有问题了 System.out.println(num1); int num2 = (int) 60000000000L; // 同样使用强制转换的操作,注意:这里右侧的数据是超出左侧数据类型的范围了 System.out.println(num2); // 结果是-129542144 ,数据溢出 } }
结果:
所以在进行强制转换的时候,是需要考虑转换前后数据范围是否符合的。
例2:public class DataAutoChange { public static void main(String[] args) { int num1 = (int) 3.5; System.out.println(num1); // 结果是3,精度损失 } }
结果:
编译过程不会出错,但是实际数据和原来的数据是不一样的,这就存在了精度丢失 -
不同数据类型进行运算操作:
- byte/short/char这三种类型都可以发生数学运算,例如"+"
- byte/short/char 在进行运算的时候,会先被转为int类型,然后再运算;
=
例1:char
public class DataAutoChange { public static void main(String[] args) { char zifu1 = 'A'; // 一旦char类型进行运算,字符会按照ASCII/unicode进行转换 System.out.println(zifu1 + 0); // 66 } }
结果:
例2:bytepublic class DataAutoChange { public static void main(String[] args) { byte num1 = 40; byte num2 = 50; // byte result1 = num7+num8; // byte+byte --> int+int = int ; 从int转换到byte可能会有损失 int result1 = num1 + num2; System.out.println(result1); byte result2 = (byte) (num1 + num2); // 在计算后,将结果强制转换也是可以的,但是要注意数据的范围 System.out.println(result2); } }
结果:
例3:short
public class DataAutoChange { public static void main(String[] args) { byte num1 = 40; short num2 = 60; short result2 = (short) (num1+num2); // byte+short ==> int+int ==> int; // 从int转换到short可能会有损失,不能主动进行转换,可进行强制转换 //(注意必须保证数据在short范围内,否则会发生数据溢出) System.out.println(result2); } }
-
拓展:
- 对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过左侧的范围,那么javac编译器将会自动隐含得补上(byte/short/char)
- 如果右侧超出了左侧范围,那么编译器出错
例如:
public class DataAutoChange { public static void main(String[] args) { byte num1 = /*(byte)*/30; // 右侧(int)没有超过左侧(byte)的范围,是可以的 // int ==> byte ,不是自动类型转换 // byte num1 = 128; // 右侧超出左侧范围,编译器会出错 System.out.println(num1); char zifu1 = 65; // 正确写法,编译器自动补充(char) System.out.println(zifu1); // 编译器常量优化 short num2 = 10; // 正确 System.out.println(num2); } }
注意:
在给变量进行复制的时候,如果右侧的表达式中全部都是常量,没有变量,那么, 编译器javac将会直接将若干个常量表达式计算得到结果。(编译时就计算结果,不是程序运行时再计算)public class DataAutoChange { public static void main(String[] args) { short a = 4; short b = 6; // short result3 = a + b; // 错误写法,左侧需要int类型,从int转换到short可能会有损失 short result3 = (short) (a + b); // 在给变量进行复制的时候,如果右侧的表达式中全部都是常量,没有变量,那么, // 编译器javac将会直接将若干个常量表达式计算得到结果。(编译时就计算结果,不是程序运行时再计算) short result4 = 4 + 5; // 正确写法 } }
转载:https://blog.csdn.net/gymaisyl/article/details/102483386
查看评论