Difference between a += 10 and a = a + 10 in java? [duplicate]
Asked Answered
A

5

32

Are a += 10 and a = a + 10 both the same, or is there some difference between them? I got this question while studying assignments in Java.

Armillary answered 17/1, 2010 at 17:37 Comment(2)
The question that this question is a duplicate of was posted after this question, so shouldn't it be a duplicate of this instead?Caruso
@Kröw No, that doesn't really matter. See for example meta.stackoverflow.com/q/251938/2891664.Sweetbrier
Z
37

As you've now mentioned casting... there is a difference in this case:

byte a = 5;
a += 10; // Valid
a = a + 10; // Invalid, as the expression "a + 10" is of type int

From the Java Language Specification section 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.

Interestingly, the example they give in the spec:

short x = 3;
x += 4.6;

is valid in Java, but not in C#... basically in C# the compiler performs special-casing of += and -= to ensure that the expression is either of the target type or is a literal within the target type's range.

Zeb answered 17/1, 2010 at 17:44 Comment(2)
Please pardon my ignorance, but why 'a+10' is of type int, when a has been defined as byte?Henninger
@Raúl: Due to binary numeric promotion. Effectively, there's no byte +(byte, byte) operator. See docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2Zeb
A
18

There is no difference, one is shorthand for the other. Even the compiler will generate the same instructions for both.

Edit: the compiler does NOT generate the same code for both, as I just found out. Check this out:

dan$ cat Test.java
public class Test {
    public static void main(String[] args) {
        int a = 0;
        a = a + 10;
        a += 20;
    }
}

dan$ javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   bipush  10
   5:   iadd
   6:   istore_1
   7:   iinc    1, 20
   10:  return

}

So the short answer, especially for a Java beginner, or anyone who isn't worried about optimizing at the smallest level, is that they are interchangeable. The long answer will depend on me reading about iadd vs iinc.

Edit 2: Ok, I'm back. The instruction specs are (roughly) as follows:

iadd - adds the top two ints on the stack

iinc - increments a local variable by a constant

And as we saw above, we can save a couple of instructions using iinc, as long as there is a constant on the right hand side.

But what happens if we have

a += a?

Then the code looks like this:

   7:   iload_1
   8:   iload_1
   9:   iadd
   10:  istore_1

which is the same thing we get if we have a = a + a.

Anemophilous answered 17/1, 2010 at 17:38 Comment(8)
i know this. but i read there is something difference related to casting. i didnt understand so asked here to know more about that.Armillary
You should have made that clear in the topicstart.Sanbo
@danben: Glad to see the edit (as the compiler doesn't generate the same code). But once a JIT-enabled JVM (like HotSpot) gets its hands on it, my suspicion is that if there's no other effect from the expression, even the longer form will get optimized to the increment operation.Burl
Hey, where did you compile Test.java? :)Incommode
@Pascal Thivent: I left that out for brevity.Anemophilous
@T.J. Crowder: I wouldn't doubt it; I was pretty surprised to see that the instructions come out differently at compilation time.Anemophilous
Note "the compiler" is just one implementation. javac has the optimisation code taken out to reduce complexity and the optimisations had little effect (in fact sometimes made code run slower).Almazan
Why would the compiler produce an add instruction for a += a, rather than a shift left? Would that be something done by the JIT compiler instead?Longicorn
M
5

This is defined in the Java Language Specification, section 15.25.2. The salient part is:

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.

That is, in your case the difference is the implicit type cast:

byte a = 100;
a += 1000;    // compiles
a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte.
Mystify answered 17/1, 2010 at 17:51 Comment(2)
And what value would byte a = 100;a += 1000; aassign to a?Aletaaletha
The 8 least significant bits of the binary representation of 1100, just like casting an int to a byte always does.Mystify
T
4

In the expressions you show, they are equivalent, in an expression like:

array[getIndex(context)][some / complex + expression] += offset;

you get an idea in which situations the += operator (and the other assignment operators) is useful. If the expression is non-trivial, the += operator prevents mistakes and improves readability and therefore maintainability.

Tattered answered 17/1, 2010 at 17:42 Comment(0)
A
1

There are some terminologies in S/W field, I can explain this to you,

in a=a+1 assignment for a is measured after two steps

  1. System calculates the value of a (a new isolated copy is created here)
  2. System add 10 to isolated variable a then the value of isolated a is assigned to left side a

But in second case,

  1. System knows the value of a and directly add 10 to a (no isolated copy has been made here).

Hope this will be helpful to you, and one more thing, we usually use method that is a += 10; because it reduce the cost of operation, as per others one,

Anthelmintic answered 23/5, 2014 at 10:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.