Sometimes it is necessary to pass a primitive type when a (reference to an) object is expected.

For example, assume that you have a method that specifies that one of its arguments is of type Object, and you need to pass it an int:

package example;

public class PassIntTest
{
  public static void handleValue(Object value)
  {
    // Do something with value...
  }

  public static void main(String[] args)
  {
    int intValue = 56;
    handleValue(intValue); // Error
  }
}

Prior to JDK Version 5.0, the above code will produce a compile-time error:

"PassIntTest.java": cannot find symbol; symbol : method valueOf(int), location:
    class java.lang.Integer at line 13, column 17
"PassIntTest.java": Fatal Error: Unable to find method valueOf

The solution is to use a Wrapper class.  For every primitive data type, there is a corresponding wrapper class:

Primitive TypeWrapper Class
booleanBoolean
byteByte
charCharacter
shortShort
intInteger
longLong
floatFloat
doubleDouble
voidVoid

Each wrapper class has a constructor which accepts a primitive type value.  For example:

Integer intWrapper = new Integer(56);

The resulting instance “wraps” the supplied value.

Note:

  •  Each wrapper class is immutable;  that is, once the value has been wrapped, it may not be changed.
  •  Each wrapper class is final;  that is, it may not be extended.

Passing Arguments

If you wish to pass an argument of a primitive type to a method that expects a reference to an object, then you wrap the value in its corresponding wrapper class:

package example;

public class PassIntTest
{
  public static void handleValue(Object value)
  {
    // Do something with value...
  }

  public static void main(String[] args)
  {
    int intValue = 56;
    handleValue( new Integer(intValue) );
  }
}

The above code will compile, and the instance of class Integer is passed in as the object instance value.

Note: All the wrapper classes live in the java.lang package.

Returning Values

Another challenge is sometimes encountered when a method returns a reference to an object, and you would like the returned value to be a primitive type.

For example:

package example;

public class ReturnIntTest
{
  public static Integer returnValue()
  {
    return new Integer(42);
  }

  public static void main(String[] args)
  {
    int intValue = returnValue();
    System.out.println(intValue);
  }
}

which will result in a compile-time error:

"ReturnIntTest.java": incompatible types; found :
  java.lang.Integer, required: int at line 12, column 20

In this case, you can make use of convenience methods provided by the wrapper classes:

Wrapper ClassMethod
Booleanpublic boolean booleanValue()
Bytepublic byte byteValue()
Characterpublic char charValue()
Shortpublic short shortValue()
Integerpublic int intValue()
Longpublic long longValue()
Floatpublic float floatValue()
Doublepublic double doubleValue()
Void(not applicable)

For example:

package example;

public class ReturnIntTest
{
  public static Integer returnValue()
  {
    return new Integer(42);
  }

  public static void main(String[] args)
  {
    int intValue = returnValue().intValue();
    System.out.println(intValue);
  }
}

The above code will compile and run correctly.

Autoboxing & Unboxing

In Java 5.0, this need for an explicit conversion between a primitive type and its wrapper class has been automated.  The Java 5.0 compiler does automatic “autoboxing” and “unboxing” without you having to do anything explicitly.

For example, the Java 5.0 compiler will “autobox” the integer value in the following code:

package example;

public class PassIntTest
{
  public static void handleValue(Object value)
  {
    // Do something with value...
  }

  public static void main(String[] args)
  {
    int intValue = 56;
    handleValue(intValue);
  }
}

which will compile and run in Java 5.0 and beyond (only).

Similarly, the Java 5.0 compiler will “unbox” the integer value in the following code:

package example;

public class ReturnIntTest
{
  public static Integer returnValue()
  {
    return new Integer(42);
  }

  public static void main(String[] args)
  {
    int intValue = returnValue();
    System.out.println(intValue);
  }
}

It too, will compile and run, but only in Java 5.0 and beyond.

The “autoboxing” and “unboxing” that the compiler performs automatically is entirely equivalent to the manual equivalent that you had to do yourself prior to Java 5.0.