java - 添加字节时不同的编译器行为

标签 java

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 行的语句不是等价的吗?如果不是那么还有什么不同?

最佳答案

是的,这两行是等价的 - 但它们使用语言的不同部分,并且它们由 JLS 的不同部分涵盖。第 3 行是普通的 + 运算符,应用于已提升为 int 的字节,给出 int 结果。在将其分配回 byte 变量之前,必须对其进行强制转换。

第 6 行是复合赋值运算符,如 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:

  • 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.

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

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

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.

关于java - 添加字节时不同的编译器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7681201/

相关文章:

java - 使用 PrettyTime 库格式化时间

java - 从抽象泛型到非抽象非泛型

java - 表中的行顺序

java - 在 Java 字符串中替换方法的更快替代方法?

java - 带有 class.forname() 的 Spring

java - 定时器对 ScheduledThreadPoolExecutor 的限制

java - 如何验证 GWT 中的 cron 表达式

java - 是否可以在 Java 中将 String 转换为 NTLM 哈希?

java - JCO_ERROR_RESOURCE : Destination does not exist

java - 绑定(bind) JavaFx 中的 observableList