In my last post I covered Java's primitive types: byte, short, int, long, float, double, boolean, and char. In some situations you'd like to be able to work with values for these types as objects, say, to place them into data structures that can hold objects. For this purpose, as well as others, Java ships with a set of wrapper classes for the primitive types.
All of the wrappers are in the java.lang package. Their class names are simply the capitalized form of the corresponding primitive types (e.g.,
Doublefor double) except for int's wrapper,
Integer io = new Integer (42); int i = io.intValue();The wrappers all work similarly, but each one has some special features that are specific to, and very helpful for, their respective type. Let's take
Integerfor an example. It has some really useful static methods.
int i1 = Integer.parseInt ("42"); int i2 = Integer.parseInt ("2a", 16); // hexadecimal parsing String hex = Integer.toHexString (42); /// ... and back Integer i1 = Integer.valueOf ("42");Other wrappers have similar, useful methods.
Integerand the other numeric wrappers have
MAX_VALUEconstants (remember, those are public static final fields) for the smallest (most negative) and largest values those types can hold. Again, handy in many situations.
Booleanclass has a couple of very useful constants,
FALSE, which are
Booleaninstances of true and false. You should use those instead of saying
new Boolean (true)because you can avoid creating extra objects that way. In fact, you can stick to using just those two constants this way:
boolean b = someComplexExpression; Boolean bo = Boolean.valueOf (b);The
valueOfmethod returns either the
You should generally prefer using
valueOfmethods over constructors for the wrappers because the JRE might be able to reuse existing wrapper objects. Considering how frequently some values, like one and zero, are used, this could really help out with your memory usage.
I should delve just a little deeper here. Is it really OK to reuse these same objects over and over in different circumstances? It truly is, because wrapper class instances are immutable, that is, their internal states (the values they wrap) cannot be altered after the instances are constructed. This eliminates a whole host of issues with sharing the instances across your application, and in particular across different threads. It is because of this benefit that there isn't, say, a
Integer. If you need to change a wrapped value, just get a new instance instead. It's OK, the JVM can deal with it.
One final note, which I won't get into deeply: Java 5 introduced a new language feature called "autoboxing", which lets you skip the conversion between primitives and wrappers in almost all cases. So, these statements are legal now:
Integer io = 42; // autoboxing int i = io; // autounboxingAnd ... that's a wrap.