Just wanted to discuss quickly a few simple best practices for auto-boxing in Java. This will help prevent shooting ones self in the foot. These suggestions go back to my rule of thumb for auto-boxing:
If you can use primitives do it, if you can’t don’t.
So here are a few simple auto-boxing rules. These apply mostly to usages of primitives verses wrapper classes, because at the end of the day, that’s what auto-boxing is all about.
1. Avoid using wrapper classes whenever possible.
Wrapper classes should only be used whenever you absolutely cannot use a primitive. Otherwise, either auto-unbox (de-autobox) the value and use the primitives.
2. Never do math with wrappers.
This is a simple one that instinctively goes along with #1. Doing math with wrapper classes forces a auto-unboxing operation to occur for each operator. Therefore, this code will cause five auto-unboxing operations and two auto-boxing operation to occur:
Integer i = 42; i = i + i + i + i + i;
This code generates this byte code:
0: bipush 42 2: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 5: astore_0 6: aload_0 7: invokevirtual #3; //Method java/lang/Integer.intValue:()I 10: aload_0 11: invokevirtual #3; //Method java/lang/Integer.intValue:()I 14: iadd 15: aload_0 16: invokevirtual #3; //Method java/lang/Integer.intValue:()I 19: iadd 20: aload_0 21: invokevirtual #3; //Method java/lang/Integer.intValue:()I 24: iadd 25: aload_0 26: invokevirtual #3; //Method java/lang/Integer.intValue:()I 29: iadd 30: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 33: astore_0
As you can see, the valueOf method is used to auto-box the initial value and the intValue method is used to auto-unbox the values. The auto-unboxing happens five times and the auto-boxing happens twice. If we use primitives instead, this is the bytecode that is created:
2: istore_0 3: iload_0 4: iload_0 5: iadd 6: iload_0 7: iadd 8: iload_0 9: iadd 10: iload_0 11: iadd 12: istore_0
Much simpler and no object creation or method calls. This code will perform much faster than the previous example and therefore using primitives is always preferred when doing any math at all.
This applies to for loop variables and counts. Using an Integer as a loop variable can reduce performance of that loop because of the need to create new objects each loop iteration during the auto-box operation.
3. Try not to use any of the comparison operators (<, >, <=, >=, ==, etc) with wrappers.
Auto-boxing allows you to use all of the comparison operators, except the ==. It will de-autobox (auto-unbox) the values and compare them correctly. The problem here is that each comparison will cause an auto-unboxing to occur and it also promotes bad style with respect to wrapper usage. In addition, since we don’t get the == operator, to be consistent the rest of those operators should be avoided. This is more of a coding style and practices thing, but if you are going to be doing comparisons, you should probably unbox the values.
4. Avoid usage in loop statements.
Using wrapper classes in statements is not as much of a performance drain as doing math with them, but it does introduce a method call during each loop iteration in order to auto-unbox the values in order to do the comparison. This is an extension to rule #3 for capturing usages in do, while, and for loops. This usage is not preferred:
Integer len = getLength(); for (int i = 0; i < len; i++) { ... }
This will auto-unbox the len variable during each loop iteration. Although this is simply a method call to the intValue method, it should still be avoided. This is better:
Integer len = getLength(); int lenInt = len; for (int i = 0; i < lenInt; i++) { ... }
5. Always check for null values.
This is a bit teadious, but when wrapper class variables are null a NullPointerException will be thrown when doing auto-unboxing. This code illustrates this problem:
Integer len = null int lenInt = len; // Throws NullPointerException
You can use terenary expresions to prevent the NullPointerExceptions or write a toolkit to do this. Toolkits in conjunction with static imports reduce the code mess of terenary expressions. Here is an example of both:
// Terenary Integer wrapper = getValue(); int intValue = (wrapper == null) ? 0 : wrapper; // Static import toolkit import static com.inversoft.util.AutoBoxTools.*; Integer wrapper = getValue(); int intValue = unbox(wrapper, 0);
Any which way you slice it, you want some easy method for handling null values when you know that they are possible. If they aren’t possible, then this rule can be ignored.
Hi
I liked this post very much and felt it was very informing, and I just want to try and understand unboxing/boxing correctly.
Does boxing happen when you parse a primitive to a method?
ex. someMethod(int value){}
I’m just trying to figure out which is the best practice when creating methods/constructor, using primitives or wrapped primitives?
ex. MyClass(Integer id, Long value){}
vs.
ex. MyClass(int id, long value){}
Hmm not sure I formulated my question correctly, but alas english is not my native tongue, so bare with me.
dh
btw. your site was the first hit on “java boxing unboxing best practice” on google
LikeLike
Sorry for the delayed response on this… Autoboxing happens anytime you call a method, assign a variable or otherwise cast the type from a primitive to a wrapper.
The best practice depends on your needs. If you need to have a null value, then declare your method with the wrapper, otherwise use a primitive.
LikeLike
83rzx3ig751h7kbb
LikeLike
My problem with the ternary logic is that you are assuming that null means zero.
My problem with unboxing is, aside from the performance hits and the hard-to-trace null pointer exceptions, less-seasoned developers are treating the wrapper classes like they are primitives, which means that someone has to go behind them and clean up.
With the need to do so much checking and tiptoeing around auto boxing an unboxing, it is still a mystery to me why they were introduced.
LikeLike
Normally I do not learn post on blogs, but I would like to say that this write-up very pressured me to take a look at and do it! Your writing style has been amazed me. Thank you, quite great article.
LikeLike