Reputation: 1177
I am trying to understand how Java primitives and wrappers work. Let us consider the following example.
Integer sum = 0;
for(int i = 0; i < 10000; ++i) {
sum += i;
}
Since Integer is immutable and a non-primitive, the statement sum += i
will be compiled as the following
sum = new Integer(sum.intValue() + i).
This would create around 10000 Integer objects (every call to new Integer
) and the cost of sum.intValue()
of unboxing the Integer to int.
Am I right?
Upvotes: 4
Views: 1440
Reputation: 718788
Not exactly. In fact:
sum += i;
is equivalent to
sum = Integer.valueOf(sum.intValue() + i);
For small integer values, Integer.valueOf(int)
will return a cached Integer
object. That means that you will get somewhat less than 10,000 new Integer
objects created.
But "small" typically means -128 to +127 (IIRC) ... so the difference won't be significant.
As Louis Wasserman points out,object allocation is cheap, and garbage collection of objects that "die young" is even cheaper. Nevertheless, you shouldn't use primitive wrappers unnecessarily, and especially not in code like this.
Upvotes: 6
Reputation: 136002
Yes, almost 10000. This is a decomiled .class
Integer sum = Integer.valueOf(0);
for(int i = 0; i < 10000; i++)
sum = Integer.valueOf(sum.intValue() + i);
Integer.valueOf has a cache for small numbers, -128 to 127 by default, so actually 10000 - 128 Integer instances will be created
Upvotes: 1
Reputation: 213233
No it's not like that. The compound assignment operator E1 op= E2
is equivalent to E1 = (T) ((E1) op (E2))
, with the difference that E1
is only evaluated once.
From JLS 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.
So, a binary operation is performed between an Integer reference and a primitive type. In which case, the Integer reference will be unboxed, and operation will be performed, and value will again be boxed to Integer
reference. As from JLS Section 5.6.2 - Binary Numeric Promotion:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
So, no a new Integer object is not necessarily created. The expression in your loop is evaluated as:
Integer sum = Integer.valueOf(sum.intValue() + i);
And the valueOf
method may use some cached value of Integer
object(for some range).
Having said all that, I hope you are not literally using a wrapper type like that in your original code, but just for the understanding purpose. You don't need to use wrapper type, unless you really need it, and that would be rare case.
Upvotes: 2
Reputation: 41945
Prefer primitive types over Boxed types when using Loop
Yes you are correct the process of boxing and unboxing, especially in a loop can serious impede performance.
But in your case you are just looping and you should NOT be using boxed primitive here and rather use int
Upvotes: 2