using the +=, = Java operators


Why does a compilation error occur in line 1, but not in line 2?

public class text {

  public static void main(String[] args) {
    byte b1 = 127;
    b1 = b1 + 1; // 1
    b1 += 1;     // 2
  }
}
Author: Kromster, 2018-06-28

2 answers

For addition, there are 4 opcodes in the JVM - iadd, ladd, fadd, and dadd. For the integer, long, float, and double types, respectively. Therefore, the addition of two bytes will be compiled to

iload_1
iload_2
iadd
istore_3

That is, the operands will be loaded into the stack as integers and the result of the addition will be returned as an integer. And trying to store an integer in a byte without explicitly converting it may result in an overflow. What the compiler warns about.

This behavior is fixed in JLS 5.6.2:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  • If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
  • Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is converted to long.
  • Otherwise, both operands are converted to type int.

The b1 += 1; operation will be compiled to

iload_1
iconst_1
iadd
i2b
istore_1

Interesting here is the i2b opcode-conversion from integer to byte. That is, the compiler does an implicit cast types.

And this behavior is fixed in JLS 15.26.2:

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.

 11
Author: Sergey Gornostaev, 2018-06-28 06:43:20

See. documentation Compound Assignment Operators

Here the output 'b1 += 1' is interpreted as 'b1 = (byte) b1 + 1'

 4
Author: JavaJunior, 2018-06-28 06:43:00