12

Here's an oddity:

float a = 0;
a = a + Math.PI; // ERROR

and yet:

a += Math.PI; // OK!

even this works:

int b = 0;
b += Math.PI; // OK, too!

Why does the += operator allow lossy implicit type conversions?

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99
  • I have read this one on SO before but sadly I cant find the answer for you right away. If its not answered when I come back I will search a bit more for you. – buzzsawddog Nov 29 '13 at 22:16
  • Weird but yes, this is a known fact to me. I think I've met it in a preparation book about SCJP or in some other book. This is a known peculiarity, maybe that's what the language specification says. – peter.petrov Nov 29 '13 at 22:16
  • 4
    See http://stackoverflow.com/questions/8710619/java-operator – Rafael Winterhalter Nov 29 '13 at 22:18
  • If arshajii's answer (or mine, if you really think so) correctly and satisfactorily answers your question, can you please "accept" it? If neither of the answers are satisfactory, I would suggest adding a bounty to the question. – The Guy with The Hat Dec 09 '13 at 02:03

2 Answers2

16

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

Notice that there is a cast involved with the compound assignment. However, with the simple addition there is no cast, hence the error.

If we include the cast, the error is averted:

float a = 0;
a = (float) (a + Math.PI);  // works

It's a common misconception that x += y is identical to x = x + y.

arshajii
  • 127,459
  • 24
  • 238
  • 287
  • 1
    I see. A corollary question: why did the designers think it was a good idea when everywhere else Java is strongly typed? – Aleksandr Dubinsky Nov 29 '13 at 22:18
  • @AleksandrDubinsky It's hard to say. I suppose it's because you might sometimes want to increment numeric primitives by something of a different type (e.g. a float by a double, as you have). – arshajii Nov 29 '13 at 22:21
  • 3
    @AleksandrDubinsky: "Why did X design Y this way" is not a question that can usefully be answered on SO (unless the designer happens to be around). – T.J. Crowder Nov 29 '13 at 22:23
  • 2
    "sometimes want to" is usually not a motivating factor for Java designers (thank goodness). – Aleksandr Dubinsky Nov 29 '13 at 22:24
  • Think you want to increment a byte value by a certain offset. There was not literal for a byte ti Java 7. Requiring an explicit cast would have made such code quite verbose. – Rafael Winterhalter Nov 29 '13 at 22:25
  • @AleksandrDubinsky It's impossible for me to give a more concrete answer to your comment. – arshajii Nov 29 '13 at 22:28
  • 1
    @arshajii I think I got it. It's because `byte + byte` is always actually an `int`, so if `a += b` were simply `a = a + b`, then either `+=` couldn't ever be used with byte, short, and char, or the rules surrounding all this would need to become more complex. And Java designers hate complex rules. – Aleksandr Dubinsky Nov 30 '13 at 15:57
2

That's because

float a = 0;
double b = 1;
a += b;

is the equivalent of

float a = 0;
double b = 1;
a = (float)(a + b);

a += is the same as a = (<type of a>)(a +

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75