The Way of the Java/Wrapper classes

Wrapper classes

edit

For every primitive type in Java, there is a built-in object type called a wrapper class. For example, the wrapper class for int is called Integer; for double it is called Double.

Wrapper classes are useful for several reasons:


Each wrapper class contains special values (like the minimum and maximum values for the type) and methods that are useful for converting between types.

You can instantiate wrapper classes and create objects that contain primitive values. In other words, you can wrap a primitive value up in an object, which is useful if you want to invoke a method that requires an object type.


Creating wrapper objects

edit

The most straightforward way to create a wrapper object is to use its constructor:

verbatim

Integer i = new Integer (17);
Double d = new Double (3.14159);
Character c = new Character ('b');

verbatim

Technically String is not a wrapper class, because there is no corresponding primitive type, but the syntax for creating a String object is the same:

verbatim

String s = new String ("fred");

verbatim

On the other hand, no one ever uses the constructor for String objects, because you can get the same effect with a simple String value:

verbatim

String s = "fred";

verbatim

In my development environment, the Boolean wrapper class has not been implemented correctly. There is supposed to be a constructor that takes a primitive boolean as an argument, but the following code

verbatim

Boolean b = new Boolean (true);

verbatim

generates an error.

Creating more wrapper objects

edit

Some of the wrapper classes have a second constructor that takes a String as an argument and tries to convert to the appropriate type. For example:

verbatim

Integer i = new Integer ("17");
Double d = new Double ("3.14159");

verbatim

There is supposed to be a Boolean constructor that takes a String argument, but it has not been implemented in my development environment. There is no such constructor for Characters.

The type conversion process is not very robust. For example, if the Strings are not in the right format, they will cause a NumberFormatException. Any non-numeric character in the String, including a space, will cause the conversion to fail.

verbatim

Integer i = new Integer ("17.1");        // WRONG!!
Double d = new Double ("3.1459 ");       // WRONG!!

verbatim

It is usually a good idea to check the format of the String before you try to convert it.

Creating even more wrapper objects

edit

Annoyingly, there is yet another way to create wrapper objects, using class methods in the wrapper classes.

verbatim

Integer i = Integer.valueOf ("17");
Double d = Double.valueOf ("3.14159");

verbatim

These methods use the same conversion methods as the constructors (parseInt and parseDouble), so they are no more robust.

When there are two ways to do the same thing, it is probably best to choose one and stick to it consistently. In this case, I think using the constructors is much better than using valueOf, because it makes it much clearer that you are creating new wrapper objects. The name valueOf is poorly chosen; given the name, it is not at all clear what it does.

Getting the values out

edit

Java knows how to print wrapper objects, so the easiest way to extract a value is just to print the object:

verbatim

Integer i = new Integer (17);
Double d = new Double (3.14159);
System.out.println (i);
System.out.println (d);

verbatim

Alternatively, you can use the toString method to convert the contents of the wrapper object to a String

verbatim

String istring = i.toString();
String dstring = d.toString();

verbatim

Finally, if you just want to extract the primitive value from the object, there is an object method in each wrapper class that does the job:

verbatim

int iprime = i.intValue ();
double dprime = d.doubleValue ();

verbatim

There are also methods for converting wrapper classes into different primitive types.

Useful methods in the wrapper classes

edit

As I mentioned, the wrapper classes contain useful methods that pertain to each type. For example, Integer contains methods for interpreting and printing integers in different bases. If you have a String that contains a number in base 6, you can convert to base 10 using parseInt.

verbatim

String base6 = "12345";
int base10 = Integer.parseInt (base6, 6);
System.out.println (base10);

verbatim

Since parseInt is a class method, you invoke it by naming the class and the method in dot notation.

Base 6 might not be all that useful, but hexadecimal (base 16) and octal (base 8) are common for computer science related things.

In the Character class, there are lots of methods for converting characters to upper and lower case, and for checking whether a character is a number, letter, or symbol.