I spotted Java's +=, -=, *=, /= compound assignment operators (good question :)), but it had a part that I don’t quite understand. Borrowing from that question:
int i = 5; long l = 8;Then
i = i + l;will not compile buti += l;will compile fine.
The accepted answer to the linked question states that:
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.
which gives that i += l; is the same as i = (int)((i) + (l)); with the exception that i is only evaluated once.
A long may be (IIRC even is guaranteed to be) longer than an int, and thus can hold a much greater range of values.
Given that this situation can very easily cause data loss due to necessary narrowing conversion at some point during execution of the statement (either r-value expression evaluation, or assignment), why is i += l; not a compile-time error or at least warning?
It probably should be, as you said, either a compile-time error or at least warning. Most books and tutorials that I’m aware of introduce
x += y;as shorthand forx = x + y;. I honestly don’t know of any that make the distinction called out in section 15.26.2 Compound Assignment Operators of the JLS except one.In chapter 2 (puzzle 9) of Java Puzzlers: Traps, Pitfalls, and Corner Cases the authors (Joshua Bloch & Neal Gafter) ask you to provide declarations for
xandisuch that this is a legal statement:and this is not:
There are lots of solutions, including the first two lines of code that you posted in your question. The authors warn against using compound assignment operators on variables of types
byte,short, andchar, and recommend that when using these operators on variables of typeintyou should make sure that the RHS expression is not along,float, ordouble.They conclude with the following observation (emphasis mine):