Wrapper Classes in Java - Quiz

Total: 5 questions

1. 

What are wrapper classes in Java, and why do we need them?

Wrapper classes from the java.lang package hold a single primitive value as an object. Each of the eight primitive types has its own wrapper: Byte, Short, Integer, Long, Float, Double, Character, Boolean. The name matches the primitive, capitalized; the exceptions are Integer (int) and Character (char).

Wrappers let you:

  • store numbers in collections and generics (List<Integer> — List<int> does not compile);
  • represent a missing value with null;
  • convert strings to numbers and back (Integer.parseInt(), Integer.toString());
  • use constants and utility methods (Integer.MAX_VALUE, Character.isDigit(), Double.isNaN()).

Wrapper objects are immutable. The numeric wrappers extend the abstract class Number; Character and Boolean do not.

2. 

What are autoboxing and unboxing in Java? When does unboxing cause a NullPointerException?

Autoboxing is the automatic conversion of a primitive into its wrapper object; unboxing is the reverse. Since Java 5 the compiler inserts both on assignment, when passing an argument, when returning from a method and in arithmetic expressions.

Integer boxed = 42;     // Integer.valueOf(42)
int primitive = boxed;  // boxed.intValue()

Unboxing is a method call such as intValue(), so a null reference throws a NullPointerException:

Integer count = null;
int n = count;                          // NPE
int age = map.get("unknown");           // NPE if the key is missing
Integer x = flag ? map.get(key) : 0;    // NPE: the 0 forces map.get(key) to be unboxed

Also, every boxing outside the cache creates a new object, so prefer primitives in hot loops (long sum, not Long sum).

3. 

Why is a == b true for Integer a = 127, b = 127; but c == d false for Integer c = 128, d = 128;? How should wrappers be compared?

For objects, == compares references, not values. Autoboxing compiles into Integer.valueOf(), which returns pre-created objects from the internal IntegerCache for numbers from -128 to 127. So both variables holding 127 point to the same object, while each boxing of 128 creates a new one.

Byte, Short and Long cache -128..127 too, Character caches 0..127, and Float/Double have no cache. The upper bound of the Integer cache can be raised with the JVM option -XX:AutoBoxCacheMax, so never rely on ==.

Compare wrappers with equals() or Objects.equals(a, b); for ordering use compareTo() or Integer.compare(). Mind the type: Integer.valueOf(1).equals(1L) returns false, because 1L is boxed into a Long. Comparing a wrapper with a primitive via == works correctly, since the wrapper gets unboxed.

4. 

What is the difference between Integer.valueOf(String) and Integer.parseInt(String)? What happens if the string is not a number?

Both methods parse a string; the difference is the return type. Integer.valueOf("42") returns an Integer object (from the cache for -128..127), while Integer.parseInt("42") returns a primitive int. Internally, valueOf(String) calls parseInt() and boxes the result.

int count = Integer.parseInt("42");      // primitive, no object
Integer boxed = Integer.valueOf("42");   // Integer object
int bin = Integer.parseInt("101011", 2); // 43, with a radix

If you need an int, use parseInt(); if you need an object (for a collection or a nullable field), use valueOf().

For an invalid string, both methods throw the unchecked NumberFormatException: for example, for " 42" (whitespace is not trimmed), "4.2", "abc" and even null. Boolean.parseBoolean()/Boolean.valueOf() are the exception: they never throw and return false for any string other than "true" in any letter case.

5. 

Why are constructors like new Integer(42) deprecated, and what should you use instead?

The constructors of all wrapper classes (new Integer(42), new Integer("42"), new Boolean("true") and so on) were deprecated in Java 9, and since Java 16 they are marked @Deprecated(forRemoval = true) (JEP 390): they may be removed in a future release, and the compiler issues a warning.

The main reason: a constructor always creates a new object, while valueOf() may return an existing object from the cache, which saves memory. Wrappers are also treated as value-based classes, whose object identity should not matter.

Integer i1 = 42;                        // autoboxing
Integer i2 = Integer.valueOf("42");     // from a string
Boolean b1 = Boolean.valueOf("true");
Character c1 = Character.valueOf('c');
Page 1 of 1