java多重转型问题
我们来看一个简单的问题,下面的代码会打印出什么?
public class hello { public static void main(String[] args){ System.out.println((int)(char)(byte)-1); } }
相信很多人会说最终输出为-1,但是实际结果却是65535,这是为什么?
这个程序中涉及了三次类型转换,该行为紧密依赖于转型的符号拓展行为。Java使用了基于2的补码的二进制运算,因此int类型的-1用32位补码表示就是11111...1111。从int到byte的转型的很简单的,它执行了一个窄化基本类型转换,直接将8位以上的部分砍掉,留下的是11111111,任然表示的是-1.
从byte到char 的转型略微麻烦,因为byte是有符号类型,char是无符号类型(表示一个字符16位)。在将一个整数类型转换为宽度更宽的整数类型是,通常是无损的(比如int转long),但是不可能用一个字符表示一个负的byte数值。因此通常认为从byte到char的转换不是一个拓宽基本类型转换,而是拓宽并窄化基本类型转换:byte先被转换为int,然后int再转换为char 。
这些看起来比较复杂,有这样一条规则来描述从较窄的整数类型转换成较宽的整形时的符号拓展行为:如果最初的数值类型是有符号的,就进行符号拓展;如果是char,不论要转换成什么类型都执行零拓展。用这个规则再来看从byte到char 的转换,byte是有符号类型,所以会进行符号拓展,11111111拓展为1111111111111111,转换为10进制数为65535.之后从char拓宽为int也是一个简单的拓宽基本类型转换。所以最终输出为65535.