is equivalent to the explicit
int x = val.intValue();
and the value of x is 3. If val was a Short reference, the unboxing of val would invoke
val.shortValue(), and so forth. If a wrapper reference is null, an unboxing conversion will throw a
NullPointerException.
The boxing and unboxing conversions are applied automatically in many contexts, such as assignment and
argument passing, so primitives and reference types can be used almost interchangeably. However, the
conversions do not apply everywhere, and in particular you cannot directly dereference a primitive variable,
or value, as if it were an object. For example, given the int variable x, as above, the expression
x.toString() will not compile. You can, however, apply a cast to the primitive first, such as:
((Object) x).toString()
The exact contexts in which boxing and unboxing automatically occur are discussed in "Type Conversions"
on page 216.
Ideally, you would rely on boxing conversions wherever necessary, without giving it a second thought. In
practice, you need to be aware that a boxing conversion may need to allocate an instance of a wrapper class,
which consumes memory and which may fail if insufficient memory is available. Given that the wrapper
classes are immutable, two objects with the same value can be used interchangeably, and there is no need to
actually create two distinct objects. This fact is exploited by requiring that boxing conversions for certain
value ranges of certain types always yield the same object. Those types and value ranges are:
Type Range
boolean true, false
byte all values
char \u0000 to \u00ff
short -128 to 127
int -128 to 127
So given the method
static boolean sameArgs(Integer a, Integer b) {
return a == b;
}
the following invocation returns TRue:
sameArgs(3, 3)