添加字节时的不同编译器行为 [英] different compiler behavior when adding bytes

查看:165
本文介绍了添加字节时的不同编译器行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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行,如果我们不将结果强制转换为字节,则编译错误 - 这可能是因为add的结果总是int而int不适合一个字节。但显然我们不必在第6行进行类型转换。这两个语句,第3行和第6行都不等同吗?如果没有,那么还有什么不同?

On line 3, it's a compiler error if we don't typecast the result to a byte -- that may be because the result of addition is always int and int does not fit into a byte. But apparently we don't have to typecast on line 6. Aren't both statements, line 3 and line 6, equivalent? If not then what else is different?

推荐答案

是的,这两行是等价的 - 但它们使用的是语言的不同部分,它们被JLS的不同部分所覆盖。第3行是普通的+运算符,应用于已提升为 int 的字节,给出 int 结果。必须先进行转换才能将其分配回 byte 变量。

Yes, the two lines are equivalent - but they use different parts of the language, and they're covered by different parts of the JLS. Line 3 is the normal + operator, applied to bytes which have been promoted to int, giving an int result. That has to be cast before you can assign it back to a byte variable.

第6行是复合赋值运行,如 JLS第15.26.2节中所述

Line 6 is a compound assignment operator as described in section 15.26.2 of the JLS:


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

At run time, the expression is evaluated in one of two ways. If the left-hand operand expression is not an array access expression, then four steps are required:


  • 首先,左侧操作数是评估以产生变量。如果此评估突然完成,则赋值表达式出于同样的原因突然完成;不评估右侧操作数,也不进行赋值。

  • 否则,保存左侧操作数的值,然后计算右侧操作数。如果此评估突然完成,则赋值表达式会出于同样的原因而突然完成,并且不会发生任何分配。

  • 否则,左侧变量的保存值和右侧的值 - 手操作数用于执行复合赋值运算符指示的二元运算。如果此操作突然完成,则赋值表达式会因同样的原因而突然完成,并且不会发生任何赋值。

  • 否则,二进制操作的结果将转换为类型左侧变量,受到值集转换(第5.1.13节)到相应的标准值集(不是扩展指数值集),并且转换结果存储在变量中。

  • First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
  • Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
  • Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

这是使其与众不同的最后一部分(突出显示)。

It's the last part (as highlighted) that makes it different.

实际上,该部分的开头显示了等价:

In fact, the start of the section shows the equivalence:


形式的复合赋值表达式> E1 op = E2 相当于 E1 =(T)((E1)op(E2)),其中 T 的类型E1 ,但 E1 仅评估一次。

A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

这篇关于添加字节时的不同编译器行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆