Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Secure type-safe collections

Overcome the problems of the generic type containers in the Java Collections Framework

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
The Java Collections Framework (JCF), introduced in 1998 in JDK 1.2, is quickly becoming the standard for storing dynamic data in Java systems. Many new APIs use JCF's container interfaces to provide references to list-, sets-, and map-like data structures. JCF's ubiquity is evident in the new EJB 2.0 standard. The framework uses Collection, Set, and Map implementations to model one-to-many and many-to-many relationships between entity beans and dependent objects.

Note: To download this article's complete source code, see Resources.

JCF's design goals focus on simplicity and flexibility by employing the Java language features. As such, it's based on the definition of interfaces for container classes. JCF includes two independent super interfaces: java.util.Collection for storing collections of objects and java.util.Map for storing key-value pairs. Derived from these roots are more specialized interfaces, like Set, SortedSet, and List on the collection side, and SortedMap on the map side.

Remember, this article assumes that you are familiar with JCF design concepts. If you need to get up to speed, read the introductory JCF articles in Resources.

After you've used JCF for a while, you'll quickly encounter one of its problems: you can't restrict JCF's containers to store only objects of a specific type. Instead, all containers store and return objects of the common super class Object. So normally, you have to cast up all objects that you retrieve from a container. But therein lies our problem. What happens if someone inserts an object of the wrong type? Here's an example to illustrate the point:

...
List intList = new ArrayList(); //should store java.lang.Integer objects only
intList.add(new Integer(1)); //OK
intList.add("2"); //Wrong, but not detected by compiler or runtime system
...
Integer number0 = (Integer)intList.get(0); //OK
Integer number1 = (Integer)intList.get(1); //throws ClassCastException


The second object added to intList is of type String -- not Integer, as the programmer intended. The compiler can't check the type of the objects you add to the container, because it accepts them all. To make things worse, the runtime system doesn't prevent you from adding the wrong type. Only when you try to read your data back do you get the ClassCastException that tells you that somewhere, you added an object of the wrong type to your container. As you can guess, finding the responsible code can prove difficult.

Templates represent a possible solution to this problem. Indeed, they are the basis for C++'s Standard Template Library (STL). Unfortunately, the Java language doesn't include templates -- at least not yet. Therefore, JCF's designers made all containers store objects of the common super class, Object, in order to provide generic collections. On the other hand, templates present their own problems -- heavy usage bloats your binary code.

With that in mind, frameworks offer a better solution. As such, the framework presented in this article solves the problem so you can store objects of all types in a JFC collection. The framework prechecks objects as you add them to a container. If an object possesses the wrong type, the framework immediately throws the ClassCastException, making it easier to find and change the troublesome code.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources