java解惑------多重转型(解惑)

 

 

 

转载于:http://liuwei1981.iteye.com/blog/163827

 

 

这个多重转型的的程序的行为紧密依赖于转型的符号扩展行为。java使用了基于2的补码的二进制运算,因此int类型的数值-1的所有32位都是置位的。从int到byte的转型是简明的,它执行了一个窄化原生类型转换,直接将除低8位之外的所有位全部砍掉。这样留下的是一个8位都是置位的byte,它仍旧表示-1。

 

从byte到char的转型则稍微麻烦一点,因为byte是有符号类型,而char是无符号类型。在将一个整数类型转换成另一个宽度更高的整数类型时候,通常是可以保持其数值的,但是却不可能从一个char表示一个负的byte数值。因此,我们认为从byte到char的转换不是一个拓宽原生类型转换,而是一个拓宽并窄化原生类型的转换:byte被转化成int,而这个int又被转换成char。

 

所有这些听起来有些复杂,幸运的是,有一条简单的规则能够描述从较窄的整型转换成较宽的整型时候的符号扩展行为:如果最初的数值类型是有符号的,那么就执行符号扩展;如果他是char,那么不管它将要被转换成什么类型,都执行零扩展

 

因为byte是有符号类型,所以在将byte数值-1转换成char时候,会发生符号扩展。作为结果的char数值的16位都被置位了,因此它等于2的16次幂-1,即65535.从char到int的转型是一个拓宽原生类型转换,所以这条规则告诉我们,它将执行零扩展而不是符号扩展。作为结果的int数值也就成了65535,这正是程序打印的结果。

 

尽管这条规则描述了在有符号和无符号整数之间进行拓宽原生类型时候的符号扩展行为,最好不要编写依赖它的程序。如果你正执行一个转型从char到char的转型的拓宽原生类型转换。并且这个char是仅有的无符号整型,那么最好将你的意图明确表达出来。

 

如果你在将一个char数值c转型为一个宽度更宽的类型,并且不希望有符号扩展,那么为清晰表达意图,可以考虑一个位掩码:

int i=c & 0xffff;

 

 

========================

 

 

我在看《java 解惑》这本书时,书上是这样说的。

If you are converting from a byte b to a char and you don't want sign extension,you
must use a bit mask to surpress it.This is a common idom,so no comment is necessary.


Java codechar c=(char)(b&oxff)


If you are converting from a byte to a char and you want sign extension,write a comment.


Java codechar c=(char) b //sign extension is performed


我的问题是为什么第一种就没有符号扩展,而第二种有呢?真感觉不出它们有何区别,望大家不吝指教。

 

-----------

 

看来你还没有搞清符号们的扩展吧?

举一个例子:

byte b=-100;
b在内存中是以补码的形式存贮的:
1001 1100

如果执行char c=(char)b;
在java中,byte到char的转换不是直接进行的。
而是byte符号扩展转换到int,然后再从int转换到char,所以b要先变为int,这时增加的位全要用b的符号位填充(这就是符号扩展),变为:
1111 1111 1111 1111 1111 1111 1001 1100

下步是强制类型转换,只保留了最低的两个字节:1111 1111 1001 1100。

如果执行char c=(char)(b&0xff),同样b要转为int ,同时符号位扩展:
1111 1111 1111 1111 1111 1111 1001 1100

再与0xff想与,
 
Java code1111 1111 1111 1111 1111 1111 1001 1100
&0000 0000 0000 0000 0000 0000 1111 1111
-----------------------------------------
 0000 0000 0000 0000 0000 0000 1001 1100

再强转为char,得: 0000 0000 1001 1100。这是一个正数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值