2.2.3 变量的类型转换

在程序中,经常需要对不同类型的数据进行运算,为了解决数据类型不一致的问题,需要对数据的类型进行转换。例如,一个浮点数和一个整数相加,必须先将两个数转换成同一类型。根据转换方式的不同,数据类型转换可分为自动类型转换和强制类型转换两种,下面分别进行讲解。

1.自动类型转换

自动类型转换也称为隐式类型转换,是指两种数据类型在转换的过程中不需要显式声明,由编译器自动完成。自动类型转换必须同时满足两个条件:一是两种数据类型彼此兼容;二是目标类型的取值范围大于源类型的取值范围。例如,下面的代码:


byte b = 3;
int x = b;   

上面的代码中,使用byte类型的变量b为int类型的变量x赋值,由于int类型的取值范围大于byte类型的取值范围,编译器在赋值过程中不会丢失数据,所以编译器能够自动完成这种转换,在编译时不报告任何错误。

除了上述示例中演示的情况,还有很多类型之间可以进行自动类型转换。下面列出3种可以进行自动类型转换的情况,具体如下。

(1)整数类型之间可以实现转换。例如,byte类型的数据可以赋值给short、int、long类型的变量;short、char类型的数据可以赋值给int、long类型的变量;int类型的数据可以赋值给long类型的变量。

(2)整数类型转换为float类型。例如,byte、char、short、int类型的数据可以赋值给float类型的变量。

(3)其他类型转换为double类型。例如,byte、char、short、int、long、float类型的数据可以赋值给double类型的变量。

2.强制类型转换

强制类型转换也称为显式类型转换,是指两种数据类型之间的转换需要进行显式声明。当两种类型彼此不兼容,或者目标类型取值范围小于源类型时,自动类型转换无法进行,这时就需要进行强制类型转换。在学习强制类型转换之前,先来看个例子,如文件2-1所示。

文件2-1 Example01.java


public class Example01 {
 public static void main(String[] args){
  int num = 4;
  byte b = num;
   System.out.println(b);
 }
}

编译文件2-1,程序报错,错误信息如图2-5所示。

图2-5 文件2-1编译报错

由图2-5可知,程序提示数据类型不兼容,不能将int类型转换成byte类型,原因是将一个int型的值赋给byte类型的变量b时,由于int类型的取值范围大于byte类型的取值范围,这样的赋值会导致数值溢出,也就是说1B的变量无法存储4个字节的整数值。

针对上述情况,就需要进行强制类型转换,即强制将int类型的值赋值给byte类型的变量。强制类型转换格式如下:


目标类型  变量 =(目标类型)值 

将文件2-1中第4行代码修改为下面的代码:


byte b =(byte)num; 

修改后保存源文件,再次编译运行,程序运行结果如图2-6所示。

图2-6 文件2-1修改后的运行结果

由图2-6可知,修改代码为强制类型转换之后,程序可以正确编译运行。需要注意的是,在对变量进行强制类型转换时,如果将取值范围较大的数据类型强制转换为取值范围较小的数据类型,如将一个int类型的数转换为byte类型,极易造成数据精度丢失。下面通过一个案例演示数据精度丢失的情况,如文件2-2所示。

文件2-2 Example02.java


 1 public class Example02 {
 2  public static void main(String[] args){
 3    byte a;                // 定义byte类型的变量a
 4    int b = 298;          // 定义int类型的变量b
 5    a =(byte)b;
 6    System.out.println("b=" + b);
 7    System.out.println("a=" + a);
 8   }
 9 }

文件2-2的运行结果如图2-7所示。

图2-7 文件2-2的运行结果

文件2-2中第5行代码进行了强制类型转换,将一个int类型的变量b强制转换成byte类型,然后再将强制转换后的结果赋值给变量a。从图2-7所示的运行结果可以看出,变量b本身的值为298,然而在赋值给变量a后,a的值为42。出现这种现象的原因是,变量b为int类型,在内存中占用4个字节;byte类型的数据在内存中占用1个字节,当将变量b的类型强制转换为byte类型后,前面3个高位字节的数据丢失,数值发生改变。int类型转换为byte类型的过程如图2-8所示。

图2-8 int类型转换为byte类型的过程

多学一招:表达式类型自动提升

表达式是指由变量和运算符组成的算式。变量在表达式中进行运算时,可能发生自动类型转换,这就是表达式数据类型的自动提升。例如,一个byte类型的变量在运算期间会自动提升为int类型。先来看个例子,如文件2-3所示。

文件2-3 Example03.java


 1 public class Example03 {
 2  public static void main(String[] args){
 3   byte b1 = 3;        // 定义一个byte类型的变量
 4   byte b2 = 4;
 5   byte b3 = b1 + b2; // 两个byte类型变量相加,赋值给一个byte类型变量
 6   System.out.println("b3=" + b3);
 7   }
 8 }

编译文件2-3,程序报错,错误信息如图2-9所示。

图2-9 文件2-3编译报错

图2-9中出现了与图2-5相同的错误,这是因为在表达式b1+b2运算期间,变量b1和b2都被自动提升为int类型,表达式的运算结果也就成了int类型,这时如果将该结果赋给byte类型的变量,编译器就会报错。解决数据自动提升类型的方法就是进行强制类型转换。将文件2-3中第5行的代码修改为如下代码:


byte b3 =(byte)(b1 + b2); 

再次编译运行,程序不会报错,运行结果如图2-10所示。

图2-10 文件2-3修改后的运行结果