Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Wrapper classes

Every primitive type has a wrapper class — a class whose object holds one value of that type: int → Integer, double → Double, boolean → Boolean, char → Character (plus Long, Short, Byte and Float). Wrappers are needed wherever Java accepts only objects: in collections and in generic types.

An object instead of a number

Integer.valueOf() packs a number into an object, and intValue() takes it back out:

void main() {
    Integer box = Integer.valueOf(42);
    int number = box.intValue();
    IO.println(box);
    IO.println(number + 1);
}

Output:

42
43

The other wrappers name their methods the same way: Double.valueOf() and doubleValue(), Boolean.valueOf() and booleanValue().

Autoboxing and unboxing

You almost never have to call these methods by hand. Java packs a primitive into an object by itself (autoboxing) and unpacks the object back (unboxing) whenever the types do not match:

void main() {
    Integer count = 5;
    int next = count + 1;
 
    List<Double> prices = new ArrayList<>();
    prices.add(9.99);
    double first = prices.get(0);
 
    IO.println(next);
    IO.println(first);
}

Output:

6
9.99

In count + 1 the object was unboxed to an int, and in prices.add(9.99) the number was boxed into a Double. Lists and maps are covered in detail in the collections chapter — for now it is enough to know that they hold only objects.

Useful methods

Wrappers are also toolboxes of ready-made methods for their type. You already know Integer.parseInt() from the type conversion lesson; here are some others:

void main() {
    IO.println(Integer.MAX_VALUE);
    IO.println(Integer.compare(3, 7));
    IO.println(Character.isDigit('7'));
    IO.println(Character.isLetter('q'));
    IO.println(Character.toUpperCase('q'));
    IO.println(Boolean.parseBoolean("true"));
}

Output:

2147483647
-1
true
true
Q
true

Integer.compare(a, b) returns a negative number, zero or a positive number depending on which number is larger.

null instead of a value

A primitive variable always holds a number, but a wrapper variable can hold null — "no value". This is handy when a missing value is different from zero:

void main() {
    Integer bonus = null;
    IO.println("Bonus: " + bonus);
}

Output:

Bonus: null

Comparing with ==

For objects, == checks whether it is the same object, not whether the values are equal. Java creates Integer objects for the numbers from −128 to 127 in advance and reuses them — this is the Integer cache. So for small numbers == happens to work, and for larger ones it does not:

void main() {
    Integer a = 127;
    Integer b = 127;
    IO.println(a == b);
 
    Integer c = 128;
    Integer d = 128;
    IO.println(c == d);
    IO.println(c.equals(d));
}

Output:

true
false
true

Compare the values of wrappers with equals() or unbox them to int first.

Common mistake

Unboxing null crashes the program with a NullPointerException. This happens most often with a map: get() returns null for a missing key, and an int variable cannot accept it:

void main() {
    Map<String, Integer> stock = Map.of("apples", 10);
    int pears = stock.get("pears");
    IO.println(pears);
}

Output:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null

Use stock.getOrDefault("pears", 0), or store the result in an Integer variable and check it for null.

Thanks for reading!

Donate to the site — we work hard for you.