A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 戴祺 中级黑马   /  2015-3-20 23:43  /  902 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

接下来看看蛋疼的转型,或者强制转换。

转型是用于将一个数值从一种类型转换到另一种类型。

一般我们转换一次就够了,但是如果连续转型会发生什么变化呢?

来个例子:

public class Multicast{

       public static void main (String[] args){

               system.out.println((int)(char)(byte -1));

       }

}

它以int-1开始,从int转换为byte,再从byte转换成char,最后转回int。第一步从32位转化为8位,第二部从8位扩充到16位,第三步从16位扩充为32位。它最终会打印出来-1么?它最终会打印出来65535。

原因:转型有符号扩展行为。Java是基于补码的运算,所以int-1的所有32位都是置位的。第一步转化只保留了低8位,任然是byte类型的-1;第二步byte转char因为char是无符号类型,所以byte转char会发生符号扩展,作为结果的char数值的16位就都被置位了,其值等于2^16-1=65535;第三步此值就又转换成int类型了。

结论:如果最初数值类型是有符号的,会执行符号扩展;如果是char,不管它将要被转换成什么类型,都执行零扩展。

如果你想将char转换成无符号的更宽的类型,可以使用一位掩码:

int i=c&0xffff;

如果你想将char转换成有符号的更宽的类型,可以先将char转换为short,short与char有相同宽度但有符号:

int i=(short) c;

如果你想将byte转换成char且不希望有符号扩展,那必须用一位掩码来限制它:

char c=(char)(b&0xff);

如果你想将byte转换成char且希望有符号扩展,直接写上注释:

char c=(char)b;//sign extension is performed

我记得当初刚开始学C++没多久的时候,老师当堂问过我们一个问题。就是个很简单的变量值互换的问题,设置一个中间变量就行。但是紧接着老师问我们如果禁止用中间变量怎么办。当时好像没人能答得上来,最后老师给我们讲了位操作。我第一次认识到离散数学的威力。

看一个比较好玩的例子,现在大部分都不这么写了吧,起码得加注释。

public class CleverSwap{

      public static void main(String[]args){

             int x=1984;   /(0x7c0)

             int y=2001;   /(0x7d1)

             x^=y^=X^=y;

             System.out.println("x="+x+"y="+y);

      }

}

那么问题来了,挖掘机到底......不是,它能互换x和y么?

肯定是不能的,因为它看起来这么正常,嘿嘿......

打印出来是:x=0y=2984。

x=x^y;

y=y^x;

x=y^x;

看起来挺合理啊,Java里为什么失败了呢?

原因:Java中操作符的操作数是从左向右求值的。在上面的程序中x被提取了两次但是两次都在所有赋值操作之前。在C和C++中之所以可以是因为大部分编译器都是先计算再赋值的,从右往左。

结论:在单个表达式中不要对同一个变量赋值两次。


1 个回复

倒序浏览
嘿,还有第二帖!刚看完那个第一帖,挺有意思的。顶下作者。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马