
4-8 数据类型的转换
设计Java语言时,常常会碰上不同数据类型转换的问题,有些Java编译程序会处理,有些则需要自行处理,这将是本节的重点。
4-8-1 指定运算符自动数据类型的转换
程序设计时常看到如下表达式:
variable=operand
1.宽化类型转换
如果左边变量操作数的数据类型数值范围较广,则右边的操作数会被自动转成左边的变量操作数数据类型。
程序实例ch4_33.java:左边变量操作数的数据类型数值范围较广的应用。

执行结果

2.窄化类型转换
如果左边变量操作数的数据类型数值范围较窄,而右边的操作数会被自动转成左边的变量操作数数据类型,但是必须符合右边的操作数结果是在左边类型数据的变量范围之内。
程序实例ch4_34.java:左边变量操作数的数据类型数值范围较窄的应用。

执行结果

3.常见的错误
如果右边操作数的值超出左边变量数据类型的范围,则在编译时会看到下列错误(意义是可能有损精确度)。
错误:不兼容的类型:从XXX转换到XXX可能会有丢失。
程序实例ch4_35.java:常见的程序错误范例。

这个程序可以看到5个错误,第6行错误消息如下。

因为byte的整数范围是-128~127,300超出范围所以错误。第8行错误消息如下。

如果将0b11111111数值当作是byte,则这是-1,理论上语法正确。可是在3-2-1节讲过,Java会将所有整数设为int数据类型,所以0b11111111会被Java编译程序视为255,所以超出byte的范围,这也是在程序实例ch4_22.java及多个程序范例的应用中在设置二进制负值的byte时,增加(byte)强制类型转换的目的,4-8-3节还会介绍强制类型转换。第10、12、14行错误消息分别如下:

由于double数据类型的值3.5超出byte、int、float的范围所以分别出现上述错误。
4-8-2 自动数据类型的转换
在程序设计时常看到如下表达式。
operand operator operand
如果上述左边operand和右边operand的数据类型不同,Java编译程序会自动依下列规则执行数据类型的转换。
(1)如果有一个operand的数据类型是double,则将另一个operand数据类型也转成double。
(2)否则,如果有一个operand的数据类型是float,则将另一个operand数据类型也转成float。
(3)否则,如果有一个operand的数据类型是long,则将另一个operand数据类型也转成long。
(4)如果以上都不符合,则将两个operand转成int。
程序实例ch4_36.java:自动数据类型转换的应用。

执行结果

程序实例ch4_37.java:常见的错误1。

根据规则4,两个operand将转成int,但是左边变量是short所以上述程序将产生下列错误。

程序实例ch4_38.java:常见的错误2。

上述第6行10.0是double,所以a会被提升至double,所以计算结果是double数据类型,但是左边的x是float数据类型,所以将产生下列错误。

4-8-3 强制数据类型的转换
其实从ch4_22.java起就用了这个概念,这相当于强制转换数据类型,若是简化ch4_22.java,改写成ch4_39.java,如下。
程序实例ch4_39.java:强制转换数据类型的应用。

执行结果

上述程序第4行的(byte)就是强制将整数0b11111111转成byte数据,所以可以顺利执行。
程序实例ch4_40.java:修订ch4_38.java的错误,第6行将10.0强制改为10.0F,相当于将double改为float。

执行结果

强制转型需留意的错误,可参考下列实例。
程序实例ch4_41.java:强制转型产生的错误。下列程序第5行int数据x值是128,在程序第7行将x强制转型为byte时,结果x值0b10000000被byte解读为-128。

执行结果
