Tag: autoboxing

Java use pass-by-value semantics, instead of pass-by-reference, when passing variables to methods.

During a method call for example, Java will copy values given by the caller and will pass them to the callee method. If the variable has a primitive type, the value of the variable is copied and passed through. If the method changes the value received as argument, the variable’s value on the caller side will remain unchanged.

However, when the argument is an object, since Java copies the variable’s value and, since in this case the value is a reference (the address of the object on the heap), operations performed on that object will take effect on the caller (assuming the object has mutable state).

Code samples in this post were compiled with a JDK 6.

Wrappers

Wrappers are Java objects that encapsulate primitive types. Wrappers have two main purposes:

provide utility functions for primitive types

allow primitive types to be used where only objects are accepted

Every primitive type has a wrapper class associated.

Data Type

Wrapper Class

byte

java.lang.Byte

short

java.lang.Short

int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

char

java.lang.Character

boolean

java.lang.Boolean

Since Java 5, we can use a feature called autoboxing. Autoboxing allows us to perform conversions between primitive types and their wrappers automatically. With autoboxing it is possible to assign wrappers to primitive types and vice-versa without the necessity of calling wrapper methods to unwrap and re-wrap. These operations are usually called boxing and unboxing.

Observation: two autoboxed instances of types Boolean, Byte, Character from \u000 to \u007f (7f is 127 in decimal), Short and Integer (from -128 to 127); always pass a == test when their primitive values are the same. More about this can be found here.

Overloading

Overloading methods in Java can be a little bit difficult when many methods are eligible to match to a certain call. When this kind of situation happens, the Java compiler will use the following order of factors to determine which method will be invoked when an overloading happens:

Widening

Autoboxing

Var-args

When there is a dispute, widening is the winner over autoboxing and var-args. When there is a dispute between autoboxing and var-args, autoboxing wins.

In the example above, we first call the method doSomething passing an int as argument. As we have a widening and an autoboxing as options, widening wins and the argument is casted from int to long. In the second call, the compiler needs to decide between autoboxing and var-args. Since the first one has higher priority, autoboxing will be used. Executing the code above gives:

long
Integer Integer

Widening reference variables is also possible in Java. In this case, widening depends on inheritance and the IS-A test is used to perform the operation. Check the code below.

Observation: type castings using references are called upcast when the object is casted to one of the classes or interfaces it inherits from or implements, respectively. When the cast is made the other way round (towards a more specific object), it is called downcast.