Autoboxing and Unboxing Tips and Traps in Java


What’s Autoboxing

  • Autoboxing is just syntactic sugar to convert a primitive value into an object of the corresponding wrapper class.
  • Example: Integer i = 2; is actually equivalent to Integer i = Integer.valueOf(2);

What’s Unboxing

  • Unboxing is also just syntactic sugar to convert an object of a wrapper type to its corresponding primitive value
  • Example: int i = new Integer(1); is actually equivalent to int i = new Integer(1).intValue();

When Autoboxing/unboxing Happens

  • Passed as a primitive type into a method that accepts a wrapper type or vice versa.
  • Assigned a primitive type to a variable of wrapper type or vice versa.
  • To use them in generics
    • Java generic types only accepts objects, so when we add primitive types into the collection, autoboxing happens, when int i=list.get(0);, unboxing happens.
  • ++ or -- on a wrapper instance.
  • Mix primitive and wrapper relational or equality operator

Effective Java Item 61: Prefer primitive types to boxed primitives

Always use Objects.equals instead of ==(identity comparison) to compare wrapper class

  • From javadoc > This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range

Unboxing and NullPointerException

When mix wrapper class and primitive type, Java will auto unbox the wrapper class to primitive type(boolean, int, long, etc), if the wrapper class is Null, then it would throw NullPointerException.

In the above code, when map doesn’t contain the key, or its value is null, it would throw NullPointerException. One fix is to use Objects.equals

Widening or Boxing, but not both

  • Long l = 0; will not compile: Type mismatch: cannot convert from int to Long
  • s 0 is an int, java doesn’t first widen it to long, then autobox it to Long.

Some Puzzles

  • in l.equals(0), 0 is autoboxed to Integer then compared with Long l. > The result is true if and only if the argument is not null and is a Long object that contains the same long value as this object
  • in l == 0, Long l is first unboxed to long, then we are compare two primitive types, so it returns true.

No Widen for wrapper type

  • The following code will not compile: Type mismatch: cannot convert from Integer to Long
  • Integer and Long is not direct related (no parent, child relation), so there is no way to convert from Integer to Long/
  • Java first unbox the Integer to an int, then widen it to a long.

Widening takes priority than boxing

  • Auto widening transforms a variable to another with a wider type: from int to long etc.
  • It’s just a syntactic sugaring: (long)the_int_value;
  • Auto widening is easier and costs less than boxing.

Boxing takes priority than Varargs

  • Varargs is just a syntactic sugaring on top of arrays: javac has to create an array to wrap the parameters.
  • Boxing is easier and costs less than Varargs.

Varargs gotchas: passing an array of primitives

Performance Hit

  • Frequent autoboxing and unboxing will create unnecessary objects.

Misc Tips

  • numeric literal type is an int, not a long, it can be boxed to Integer, not Long

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)