Until today, I thought that for example:

i += j;

Was just a shortcut for:

i = i + j;

But if we try this:

int i = 5;
long j = 8;

Then i = i + j; will not compile but i += j; will compile fine.

Does it mean that in fact i += j; is a shortcut for something like this i = (type of i) (i + j)?

  • 131
    I'm surprised Java allows this, being a stricter language than its predecessors. Errors in casting can lead to critical failure, as was the case with Ariane5 Flight 501 where a 64-bit float cast to a 16-bit integer resulted in the crash. – SQLDiver Jan 5 '15 at 16:31
  • 93
    In a flight control system written in Java, this would be the least of your worries @SQLDiver – Ross Drew Nov 2 '15 at 9:24
  • 10
    Actually i+=(long)j; even will compile fine. – Tharindu Sathischandra Mar 18 '16 at 7:45
  • 6
    The constant push by one set of developers for accuracy and another for ease of use is really interesting. We almost need two versions of the language, one that is amazingly precise and one that is easy to use. Pushing Java from both directions moves it towards being unsuitable for either group. – Bill K Sep 19 '17 at 16:03
  • 3
    if it did require casting, where would you put it? i += (int) f; casts f before addition, so it's not equivalent. (int) i += f; casts the result after assignment, not equivalent either. there would be no place to put a cast that would signify that you want to cast the value after adding, but before assignment. – Norill Tempest Oct 24 '18 at 13:09

11 Answers 11




An example cited from §15.26.2

[...] the following code is correct:

short x = 3;
x += 4.6;


short x = 3;
x = (short)(x + 4.6);

In other words, your assumption is correct.

  • 40
    So i+=j compiles as I checked myself, but it would result in loss of precision right? If that's the case, why doesn't it allow it to happen in i=i+j also? Why bug us there? – bad_keypoints Sep 22 '12 at 6:07
  • 43
    @ronnieaka: I'm guessing that the language designers felt that in one case (i += j), it is safer to assume that the loss of precision is desired as opposed to the other case (i = i + j) – Lukas Eder Sep 22 '12 at 8:31
  • 11
    No, its right there, infront of me! Sorry i didn't notice it earlier. As in your answer, E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), so that's kind of like implicit down typecasting (down from long to int). Whereas in i = i+j, we have to do it explicitly, ie, provide the (T) part in E1 = ((E1) op (E2)) Isn't it? – bad_keypoints Sep 22 '12 at 14:52
  • 8
    A likely reason to why the Java compiler adds a typecast is because if you're trying to perform arithmetic on incompatible types, there is no way of performing a typecast of the result using the contracted form. A typecast of the result is generally more accurate than a typecast of the problematic argument. No typecast would make the contraction useless when using incompatible types, as it would always cause the compiler to throw an error out. – ThePyroEagle Dec 22 '15 at 21:04
  • 5
    It's not rounded. It's cast (= truncated) – Lukas Eder Apr 3 '16 at 12:40


byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57


byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40


char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'


char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'
  • 11
    @AkshatAgarwal ch is a char. 65 * 1.5 = 97.5 -> Got it? – Sajal Dutta May 5 '14 at 22:07
  • 77
    Yeah, but I can just see some beginner coming here, reading this, and going away thinking that you can convert any character from upper case to lower case by multiplying it by 1.5. – Dawood says reinstate Monica May 28 '14 at 9:25
  • 100
    @DavidWallace Any character as long as it is A ;) – Peter Lawrey May 28 '14 at 12:56
  • 14
    @PeterLawrey & @DavidWallace I will reveal your secret- ch += 32 =D – Minhas Kamal Mar 16 '16 at 5:29

Very good question. The Java Language specification confirms your suggestion.

For example, the following code is correct:

short x = 3;
x += 4.6;


short x = 3;
x = (short)(x + 4.6);
  • 13
    Or more fun: "int x=33333333; x+=1.0f;". – supercat Apr 20 '17 at 19:31
  • 4
    @supercat , what trickery is this? A widening conversion that is incorrectly rounded, followed by an addition that doesn't actually change the result, casting to int again to produce a result that is most unexpected for normal human minds. – neXus Sep 21 '18 at 12:33
  • 1
    @neXus: IMHO, the conversion rules should have treated double->float as widening, on the basis that values of type float identify real numbers less specifically than those of type double. If one views double as a complete postal address and float as a 5-digit postal code, it's possible to satisfy a request for a postal code given a complete address, but it's not possible to accurately specify a request for a complete address given just a postal code. Converting a street address to a postal code is a lossy operation, but... – supercat Sep 21 '18 at 15:05
  • 1
    ...someone who needs a complete address wouldn't generally be asking for just a postal code. Conversion from float->double is equivalent to converting US postal code 90210 with "US Post Office, Beverly Hills CA 90210". – supercat Sep 21 '18 at 15:07


basically when we write

i += l; 

the compiler converts this to

i = (int)(i + l);

I just checked the .class file code.

Really a good thing to know

  • 3
    Can you tell me which classfile this is? – ζ-- Aug 12 '13 at 14:29
  • 6
    @hexafraction: what you mean by class file? if you asking about the class file i mentioned in my post than it's the complied version of your java class – Umesh Awasthi Aug 12 '13 at 15:17
  • 3
    Oh, you mentioned "the" class file code, which led me to believe a specific classfile was involved. I understand what you mean now. – ζ-- Aug 12 '13 at 18:57
  • 62
    Of all letters, you actually chose "l" (lowercase L)... – Bogdan Alexandru Sep 23 '14 at 9:51
  • 7
    @glglgl I disagree that one should rely on font to distinguish in those cases... but everybody has the freedom to choose what thinks is best. – Bogdan Alexandru Feb 16 '15 at 14:42

you need to cast from long to int explicitly in case of i = i + l then it will compile and give correct output. like

i = i + (int)l;


i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

but in case of += it just works fine because the operator implicitly does the type casting from type of right variable to type of left variable so need not cast explicitly.

  • 7
    In this case, the "implicit cast" could be lossy. In reality, as @LukasEder states in his answer, the cast to int is performed after the +. The compiler would (should?) throw a warning if it really did cast the long to int. – Romain Jan 3 '12 at 10:17

The problem here involves type casting.

When you add int and long,

  1. The int object is casted to long & both are added and you get long object.
  2. but long object cannot be implicitly casted to int. So, you have to do that explicitly.

But += is coded in such a way that it does type casting. i=(int)(i+m)


In Java type conversions are performed automatically when the type of the expression on the right hand side of an assignment operation can be safely promoted to the type of the variable on the left hand side of the assignment. Thus we can safely assign:

 byte -> short -> int -> long -> float -> double. 

The same will not work the other way round. For example we cannot automatically convert a long to an int because the first requires more storage than the second and consequently information may be lost. To force such a conversion we must carry out an explicit conversion.
Type - Conversion

  • 2
    Hey, but long is 2 times larger than float. – Sarge Borsch Aug 30 '13 at 10:17
  • 10
    A float can't hold every possible int value, and a double can't hold every possible long value. – Alex MDC Sep 9 '13 at 20:41
  • 2
    What do you mean by "safely converted" ? From latter part of the answer I can deduce that you meant automatic conversion ( implicit cast ) which is of course not true in case of float -> long. float pi = 3.14f; long b = pi; will result in compiler error. – Luke Nov 7 '13 at 13:21
  • 1
    You'd be better off differentiating floating point primitive types with integer primitive types. They're not the same thing. – ThePyroEagle Dec 22 '15 at 20:59
  • Java has simplistic conversion rules that require the use of casts in many patterns where behavior without casts would otherwise match expectations, but doesn't require casts in many patterns that are usually erroneous. For example, a compiler will accept double d=33333333+1.0f; without complaint, even though the result 33333332.0 would likely not be what was intended (incidentally, the arithmetically-correct answer of 33333334.0f would be representable as either float or int). – supercat Apr 20 '17 at 19:40

Sometimes, such a question can be asked at an interview.

For example, when you write:

int a = 2;
long b = 3;
a = a + b;

there is no automatic typecasting. In C++ there will not be any error compiling the above code, but in Java you will get something like Incompatible type exception.

So to avoid it, you must write your code like this:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting
  • 6
    Thanks for the insight regarding the comparison of the op use in C++ to its use in Java. I always like seeing these bits of trivia and I do think they contribute something to the conversation that may often be left out. – Thomas Jan 14 '15 at 20:50
  • 2
    However the question itself is interesting, asking this in an interview is stupid. It does not prove that the person can produce a good quality code - it just proves that he had enough patience to prepare for an Oracle certificate exam. And "avoiding" the incompatible types by using a dangerous auto-conversion and thus hiding the possible overflow error, probably even proves that the person is not able to produce probable a good quality code. Damn the Java authors for all these auto-conversions and auto-boxing and all! – Honza Zidek Mar 26 '18 at 11:08

The main difference is that with a = a + b, there is no typecasting going on, and so the compiler gets angry at you for not typecasting. But with a += b, what it's really doing is typecasting b to a type compatible with a. So if you do

int a=5;
long b=10;

What you're really doing is:

int a=5;
long b=10;
  • 5
    Compound assignment operators perform a narrowing conversion of the result of the binary operation, not the right-hand operand. So in your example, 'a += b' is not equivalent to 'a = a + (int) b' but, as explained by other answers here, to 'a = (int)(a + b)'. – Lew Bloch Jan 9 '16 at 21:14

Subtle point here...

There is an implicit typecast for i+j when j is a double and i is an int. Java ALWAYS converts an integer into a double when there is an operation between them.

To clarify i+=j where i is an integer and j is a double can be described as

i = <int>(<double>i + j)

See: this description of implicit casting

You might want to typecast j to (int) in this case for clarity.

  • 1
    I think a more interesting case might be int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;. Adding zero to someInt shouldn't affect its value, but promoting someInt to float may change its value. – supercat Aug 13 '18 at 20:27

Java Language Specification defines E1 op= E2 to be equivalent to E1 = (T) ((E1) op (E2)) where T is a type of E1 and E1 is evaluated once.

That's a technical answer, but you may be wondering why that's a case. Well, let's consider the following program.

public class PlusEquals {
    public static void main(String[] args) {
        byte a = 1;
        byte b = 2;
        a = a + b;

What does this program print?

Did you guess 3? Too bad, this program won't compile. Why? Well, it so happens that addition of bytes in Java is defined to return an int. This, I believe was because the Java Virtual Machine doesn't define byte operations to save on bytecodes (there is a limited number of those, after all), using integer operations instead is an implementation detail exposed in a language.

But if a = a + b doesn't work, that would mean a += b would never work for bytes if it E1 += E2 was defined to be E1 = E1 + E2. As the previous example shows, that would be indeed the case. As a hack to make += operator work for bytes and shorts, there is an implicit cast involved. It's not that great of a hack, but back during the Java 1.0 work, the focus was on getting the language released to begin with. Now, because of backwards compatibility, this hack introduced in Java 1.0 couldn't be removed.

protected by Gilbert Le Blanc Feb 27 '13 at 9:08


Would you like to answer one of these unanswered questions instead?
