Like every other class
, Integer
is a reference type. This means it can only be accessed indirectly, via a reference. You cannot store an instance of a reference type in a field, a local variable, a slot in a collection, etc. -- you always have to store a reference and allocate the object itself separately. There are a variety of reasons for this:
- You need to be able to represent
null
.
- You need to be able to replace it with another instance of a subtype (assuming subtypes are possible, i.e. the class is not
final
). For example, an Object[]
may actually store instances of any number of different classes with wildly varying sizes.
- You need to preserve sharing, e.g. after
a[0] = a[1] = someObject;
all three must refer to the same object. This is much more important (vital even) if the object is mutable, but even with immutable objects the difference can be observed via reference equality checks (==
).
- You need reference assignment to be atomic (cf. Java memory model), so copying the whole instance is even more expensive than it seems.
With these and many other constraints, always storing references is the only feasible implementation strategy (in general). In very specific circumstances, a JIT compiler may avoid allocating an object entirely and store its directly (e.g. on the stack), but this is an obscure implementation detail, and not widely applicable. I only mention this for completeness and because it's a wonderful illustration of the as-if rule.