这里要说到的问题来自于这样的一个Java程序:
public class CastTest {
public static void main(String[] args) {
System.out.println((int)(char)(byte)-1);
}
}
在这个程序中,-1经过三次数据类型转换:由int转为byte,再由byte转为char,最后由char转为int,输出的结果还是-1吗?
No!结果不再是-1了,而是65535!
接下来让我们来看看这是怎么回事呢?
由int(32位)转为byte(8位),数据从32位窄化成了8位,即:
由11111111 11111111 11111111 11111111(32位)转成了1111 1111(8位),结果还是-1,符号没变。
由byte(8位)转为char(16位)的这一过程与上面稍微有点不同。byte类型不能直接转为char。数据先由byte转为int(基础数据类型的默认转换),数据从8位拓宽到了16位,
即由11111111 (8位)转为11111111 11111111 11111111 11111111 (32位);
再由int转为char,数据从32位窄化成了16位,
即由11111111 11111111 11111111 11111111 (32位)转为
1111 1111 1111 1111 (16位)。
最后数据由char(16位)转为int(32位)。在这一过程中,数据从16位拓宽成了32位,
由11111111 11111111 (16位)转为00000000 00000000 11111111 11111111 (32位,前16位为0,后16位为1),这个数作为int类型,转为十进制为65535,所以最后程序的结果是65535。
从上面的转换过程中我们可以发现:
数据从byte转为int,即由11111111 (8位)转为11111111 11111111 11111111 11111111 (32位)这一步中,数据的符号没有发生变化,都是-1。而由char转为int的过程中,即由11111111 11111111 (16位)转为00000000 00000000 11111111 11111111 (32位,前16位为0,后16位为1),数据变成了正数。这是因为从较窄的整型转为较宽的整型过程中,如果最初的数据是有符号的,那么将执行符号扩展;如果最初的数据是char类型,将执行0扩展(简单地说,char类型不支持符号扩展。以上问题的根源在于char。)。
根据以上结论,我们再来看这样两条语句:
System.out.println((int)(short)(byte)-1);
System.out.println((int)(double)(float)-1);
结果又分别是什么呢?不错,都是-1。