Venk K
Venk K

Reputation: 1177

Java Primitives and Primitive Wrappers

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

Answers (4)

Stephen C
Stephen C

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

Evgeniy Dorofeev
Evgeniy Dorofeev

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

Rohit Jain
Rohit Jain

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

Narendra Pathai
Narendra Pathai

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

Related Questions