Item 49 - Prefer primitive types to boxed primitives

From Effective Java 2/e by Joshua Bloch

Three differences

  1. Primitives have only their values, whereas boxed primitives have identities distinct from their values
  2. Primitive types have only fully functional values, whereas each boxed primitive type has one nonfunctional value which is null
  3. Primitives are generally more time- and space-efficient than boxed primitives

Example #1

// naturalOrder.compare(new Integer(42), new Integer(42)) == 1 (should be 0)
Comparator<Integer> naturalOrder = new Comparator<Integer>() {
   public int compare(Integer first, Integer second) {
      return first < second ? -1 : (first == second ? 0 : 1);
   }
};

// naturalOrder.compare(new Integer(42), new Integer(42)) == 0
Comparator<Integer> naturalOrder = new Comparator<Integer>() {
   public int compare(Integer first, Integer second) {
      int f = first;   // Auto-unboxing
      int s = second;  // Auto-unboxing
      return f < s ? -1 : (f == s ? 0 : 1); // No unboxing
   }
};

Example #2

// It throws a NullPointerException when evaluating the expression (i == 42)
public class Unbelievable {
   static Integer i;
   public static void main(String[] args) {
      if (i == 42)
         System.out.println("Unbelievable");
   }
}

In nearly every case when you mix primitives and boxed primitives in a single operation, the boxed primitive is auto-unboxed

Example #3

// Hideously slow program! Can you spot the object creation?
public static void main(String[] args) {
   Long sum = 0L;
   for (long i = 0; i < Integer.MAX_VALUE; i++) {
      sum += i;
   }
   System.out.println(sum);
}

Conclusion

  • Autoboxing reduces the verbosity, but not the danger, of using boxed primitives
  • When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw a NullPointerException

Posted by The Finest Artist