2011-10-06 71 views
5
byte b1 = 3; 
byte b2 = 0; 

b2 = (byte) (b2 + b1); // line 3 
System.out.println(b2); 

b2 = 0; 
b2 += b1;    // line 6 
System.out.println(b2); 

在第3行中,如果我们不将结果转换为字节 - 这可能是因为加法结果始终为int且int不适合一个字节。但显然我们不需要在第6行上进行类型转换。第3行和第6行的两个语句都不相等吗?如果不是,那么还有什么不同?添加字节时的不同编译器行为

回答

10

是的,这两行是等价的 - 但它们使用语言的不同部分,并且它们被JLS的不同部分覆盖。第3行是正常的+操作符,应用于已提升为int的字节,给出int结果。在将其分配回byte变量之前必须先进行演示。

第6行是作为section 15.26.2 of the JLS所述的化合物赋值操作符:

在运行时,该表达在两种方式之一进行评估。如果左边的操作数的表达不是数组访问表达式,那么需要四个步骤:

  • 首先,左边的操作数进行评估,以产生可变的。如果此评估突然完成,则由于相同的原因,分配表达式会突然完成;右侧的操作数不会被评估,也不会进行分配。
  • 否则,保存左侧操作数的值,然后评估右侧操作数。如果此评估突然完成,则由于同样的原因,分配表达式会突然完成,并且不会进行分配。
  • 否则,左侧变量的保存值和右侧操作数的值用于执行复合赋值运算符指示的二进制运算。如果此操作突然完成,则由于同样的原因,赋值表达式会突然完成并且不会发生分配。
  • 否则,将二进制运算的结果转换为左侧变量的类型,将值集转换(第5.1.13节)转换为适当的标准值集(而不是扩展指数值集),并将转换结果存储到变量中。

这是最后一部分(突出显示),使它不同。

事实上,该部分的开始示出了等价:

形式E1 OP = E2相当于E1 =(T)((E1)的运算中的化合物,赋值表达式( E2)),其中TE1的类型,除了E1仅评估一次。

+1

没有更多的问题,你的荣幸。 – f1sh

+2

感觉很好,让我的第一个问题由Jon Skeet回答:) – Zohaib

-2

Java使涉及整型的操作和转换变得一团糟。最好的建议是,尽可能使用int。避免byte/short/char,在进行任何计算之前明确将它们转换为int

+2

为什么你会在Jon Skeet对“混乱”是如何工作的一个非常详细的解释后2个小时发帖?有时使用“int”以外的类型是有道理的。 – EboMike