Raw/Generic Type ComparisonS2C Home « Raw/Generic Type Comparison

In this lesson we compare code that uses raw types with code using generic types and contrast the results to see the benefits of strongly typed code.

Lets take a look at some non-generic code and the pitfalls associated with type safety and then use some type safe generic code to do the same thing.

Raw Type Example Top

First we will create a raw type collection where we only want String objects stored and add an Integer object:


package com.server2client;
/*
  Test class for Raw Type Collection
*/
import java.util.*; // Import the java.util package

public class RawTypeNameCollection {
    /*
     Raw Type name ArrayList containing only String instances
    */ 
    private static final List names = new ArrayList();

    public static void main (String[] args) {
        // Add to our collection
        names.add("Bill");
        names.add("Ben");

        // Nothing to stop us adding an Integer
        names.add(6);

        // Iterate over our collection
        for (Object name : names) {
            String aName = (String) name;  // ClassCastException (on Integer)
            System.out.println(aName);  // Print name
        }
    }
}

Building the RawTypeNameCollection class produces the following output:

Build raw type
Screenshot 1. Building the RawTypeNameCollection class.

As you can see the program builds but the compiler gives us warning messages which we ignore at our peril. The compiler is basically telling us we are using non generic code for our polymorphic List and hence is not type safe. So the compiler has done its job and told us we are using a raw type, but the code is still executable because legacy code is still allowed. Lets run the code:

Running the RawTypeNameCollection class produces the following output:

Run raw type
Screenshot 2. Running the RawTypeNameCollection class.

As expected we get a ClassCastException when we iterate over the Integer object. You can imagine a scenario where our collection is public and accessed elsewhere and the effort involved to track down the erroneous code.

Generic Type Example Top

Now we will create a generic type collection where we only want String objects stored and add an Integer object:


package com.server2client;
/*
  Test class for Generic Type Collection
*/
import java.util.*; // Import the java.util package

public class GenericTypeNameCollection {
    /*
     Generic Type name ArrayList containing only String instances
    */ 
    private static final Collection<String> names = new ArrayList<>();

    public static void main (String[] args) {
        // Add to our collection
        names.add(new String("Bill"));
        names.add(new String("Ben"));

        // Now try adding an Integer
        names.add(new Integer(6));

        // Now use a parameterised type iterator to iterate over our collection
        for (Iterator<String> i = names.iterator(); i.hasNext(); ) {
            String aName = i.next(); // No cast required
            System.out.println(aName);  // Print name
        }

        // Use enhanced for loop to iterate over collection (preferred)
        for (String s : names) { // No cast required
            System.out.println(s);  // Print name
        }
    }
}

Building the GenericTypeNameCollection class produces the following output:

Build generic type
Screenshot 3. Building the GenericTypeNameCollection class.

The build fails when we try to add an Integer to our type safe ArrayList<String> which is exactly what we want. There is now no chance of getting a ClassCastException at runtime as the code won't even compile. If our collection was public and someone tried to put in anything else other than String objects they won't even get a clean compile. Remove the code that tries to insert the Integer object and run the class:

Run generic type
Screenshot 4 . Building the GenericTypeNameCollection class.

We iterate over the loop twice, the first time with a parameterised type iterator and the second time using the enhanced for loop introduced in Java 5. In neither case do we need to cast as the compiler has already inserted casts for us when compiling the code. Also using the enhanced for loop is much easier to write, more elegant and recommended when iterating over collections.

Related Quiz

Generics Quiz 2 - Raw/Generic Type Quiz

Lesson 2 Complete

In this lesson we compared raw and generic types and looked at the advantages generics brings.

What's Next?

In the next lesson we look at generic interfaces.