byte b,b1=3, b2=0;b2+=3; //     1b=3+4;   //   2b2=b1+1; //   3语句1和语句2能编译通过,语句3不能,需强制转换b2=(byte)(b1+1),那么语句1和2为什么不用转换也能通过呢

解决方案 »

  1.   

    b2+=3;
    包含了一个隐藏的类型转换!
    b2=b1+1;
    却没有隐藏的转型,需要自己强制转换,整数默认是int型的。
    这个问题在《java解惑》一书的谜题9中有详细解释 
    现在该轮到你来写些代码了,好消息是,你只需为这个谜题编写两行代码,并为下一个谜题也编写两行代码。这有什么难的呢?我们给出一个对变量x和i的声明即可,它肯定是一个合法的语句: 
    x += i;但是,它并不是: 
    x = x + i;许多程序员都会认为该迷题中的第一个表达式(x += i)只是第二个表达式(x = x + i)的简写方式。但是这并不十分准确。这两个表达式都被称为赋值表达式。第二条语句使用的是简单赋值操作符(=),而第一条语句使用的是复合赋值操作符。(复合赋值操作符包括 +=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、^=和|=)Java语言规范中讲到,复合赋值 E1 op= E2等价于简单赋值E1 = (T)((E1)op(E2)),其中T是E1的类型,除非E1只被计算一次。
    换句话说,复合赋值表达式自动地将它们所执行的计算的结果转型为其左侧变量的类型。如果结果的类型与该变量的类型相同,那么这个转型不会造成任何影响。然而,如果结果的类型比该变量的类型要宽,那么复合赋值操作符将悄悄地执行一个窄化原始类型转换。因此,我们有很好的理由去解释为什么在尝试着执行等价的简单赋值可能会产生一个编译错误。——摘自《java解惑》
      

  2.   

    b2+=3;这个是默认帮你装换的。b=3+4;这个是因为也是因为在一定范围内(好像是-128-128),不需要强制装换,也是默认帮你装换的。这是我前几天看的一本叫《java细节》书里的有的。
      

  3.   

    其实对于Character和Integer与int ,char之间的转换关系,才真的麻烦。
      

  4.   

    b=3+4; // 3+4常量表达式的值并未超出byte的表示范围。编译之后为b=7;所以没问题。var op=expr等价于var=(T)((var)op(expr))
    这就不难看出第3个表达式的问题:整型提升后运算完毕,没有强制回转。所以出错。参见《java程序设计语言第四版》中文版第143页。
      

  5.   


    byte b,b1=3, b2=0;b2+=3; //     1b=3+4;   //   2b2=b1+1; //   3语句1和语句2能编译通过,语句3不能,需强制转换b2=(byte)(b1+1),那么语句1和2为什么不用转换也能通过呢
    第一个b2参与算术运算,自动提升为int型,第二个就不用说了,3+4可以是byte型,第三个,b1参与算术运算,自动提升为int型,所以b1+1属于int型,而b2 为byte型,所以需要强制转换。