Home > Articles > Programming > Java

Generics 101: Mastering the Fundamentals

Jeff Friesen
  • PrintPrint
  • Share ThisShare This
  • DiscussDiscuss
Close WindowJeff Friesen

Jeff Friesen

Learn more…

Using Transitions to Simplify JavaFX Animations
Sep 9, 2009
Styling Swing Components with Java CSS
Aug 28, 2009
Show Me the Movie with DirectShow
Apr 28, 2009
Playing Media with Java Media Components
Feb 27, 2009
Creating Java User Interfaces with Project Scene Graph
Feb 10, 2009
Blending Images in Java
Sep 12, 2008
Introduce Animated Cursors to Java GUIs, Part 3
Apr 30, 2008
Introduce Animated Cursors to Java GUIs, Part 2
Apr 18, 2008
Introduce Animated Cursors to Java GUIs, Part 1
Apr 11, 2008
Enhance Java GUIs with Windows Icons
Apr 4, 2008
Taming Mustang, Part 2: Scripting API Tour
Nov 2, 2007
Visit Java's Relatives: Jython and Groovy
May 4, 2007
Generics 101: Mastering the Fundamentals
Mar 23, 2007
Taming Mustang, Part 3: A New Script Engine
Mar 2, 2007
Taming Mustang, Part 1: Collections API
Feb 16, 2007
PCX Meets Image I/O: Creating an Image-Reading Java Plug-in
Dec 29, 2006
Mustang (Java SE 6) Gallops into Town
Oct 20, 2006
GridBagLayout Versus FormLayout
Oct 6, 2006
Laying Out Realistic GUIs the GridBagLayout Way
Sep 29, 2006
Harness the Power of Java's GridBagLayout
Sep 22, 2006
Tools of the Trade: SwingX Meets Swing with New and Extended Components
Aug 4, 2006
Have Fun with the Custom Screensavers Library
Mar 10, 2006
Build Screensavers with a Custom Screensavers Library in Borland C++
Feb 24, 2006
Tools of the Trade: Flash meets Java with Transform SWF and JFlashPlayer
Feb 17, 2006
Tools of the Trade, Part 3: Using the JGoodies Animation Library
Dec 22, 2005
Tools of the Trade, Part 2: Building Graphs with JGraph
Dec 9, 2005
Tools of the Trade, Part 1: Creating PDF documents with iText
Nov 4, 2005
From Literals to Expressions in Java
Aug 16, 2002
Build Your Own Java-Based Email Programs
May 10, 2002
Exploring Java's Network API: URIs and URLs
May 1, 2002
Exploring Java's Network API: Sockets
Apr 19, 2002
Basic Thread Operations in Java
Mar 22, 2002
Working with Streams in Java
Mar 22, 2002
Advanced Tips for More Powerful Tables
Nov 20, 2001
Exploring Swing's Table Component
Nov 20, 2001
Simple Tips for More Powerful Tables
Nov 20, 2001
A Handful of Tips for Swing Programs
Apr 13, 2001
A Trio of Tips for AWT Programs
Apr 13, 2001
Automating Programs with Robots
Apr 13, 2001
Build Your Own Media Player
Apr 13, 2001
Drawing Cubic Curves
Apr 13, 2001
Scaling Images
Apr 13, 2001
Using the Swing API Timers
Apr 13, 2001

Sorry, this author hasn't posted any blogs.

AJAX and JavaServer™ Faces (Digital Short Cut)

Like this article? We recommend
AJAX and JavaServer™ Faces (Digital Short Cut)

Java 2 Standard Edition 5.0 introduced generics to Java developers. Since their inclusion in the Java language, generics have proven to be controversial: many language enthusiasts believe that the effort to learn generics outweighs their importance to the language. Fortunately, as Jeff Friesen discusses here, you can master the fundamentals without expending much effort.

Java 2 Standard Edition 5.0 introduced generics to Java developers. Since their inclusion in the Java language, generics have proven to be controversial: many language enthusiasts believe that the effort to learn generics outweighs their importance to the language. Fortunately, as this article shows, you can master the fundamentals without expending much effort.

This article helps you master generics fundamentals by first focusing on type safety, in which you discover the motivation for adding generics to Java. The article next explores generic types and generic methods, which manifest generics at the source code level. For brevity, this article focuses on essentials and does not delve into too many details—complete coverage of generics would probably occupy an entire book.

Type Safety

Java developers strive to create Java programs that work correctly for their clients—no developer wants code to fail and then be faced with an angry client. Failure is typically indicated through thrown exceptions; ClassCastExceptions (resulting from improper casting) are among the worst because they usually are not expected (and are not logged so that their causes can be found). Take a look at Listing 1.

Listing 1 BeforeGenerics.java

// BeforeGenerics.java

import java.util.*;

public class BeforeGenerics
{
  public static void main (String [] args)
  {
   List l = new ArrayList ();

   l.add (new Double (101.0));
   l.add (new Double (89.0));
   l.add (new Double (33.0));

   double avg = calculateAverage (l);
   System.out.println ("Average = " + avg);

   l.add ("Average");
   avg = calculateAverage (l);
   System.out.println ("Average = " + avg);
  }

  static double calculateAverage (List l)
  {
   double sum = 0.0;
   Iterator iter = l.iterator ();
   while (iter.hasNext ())
     sum += ((Double) iter.next ()).doubleValue ();

   return sum / l.size ();
  }
}

Listing 1 averages the floating-point values in a java.util.List-referenced java.util.ArrayList of Double objects. Somewhere in this source code lurks a bug that leads to a ClassCastException. If you compile BeforeGenerics.java with a pre-J2SE 5.0 compiler, no error/warning message outputs. Instead, you only discover this bug when you run the program:

Average = 74.33333333333333
Exception in thread "main" java.lang.ClassCastException: java.lang.String
    at BeforeGenerics.calculateAverage(BeforeGenerics.java:28)
    at BeforeGenerics.main(BeforeGenerics.java:19)

From a technical perspective, the ClassCastException results from l.add ("Average"); and sum += ((Double) iter.next ()).doubleValue ();. This exception is thrown when iter.next() returns the previously added String and the cast from String to Double is attempted.

This exception indicates that the program is not type safe; it arises from assuming that collections are homogeneous—they store objects of a specific type or of a family of related types. In reality, these collections are heterogeneous—they are capable of storing any type of object because the element type of collections is Object.

Although ClassCastExceptions can occur from many sources, they frequently result from violating the integrity of a collection that is considered to be homogeneous. Solving collection-oriented type safety problems motivated the inclusion of generics in the Java language (and an overhaul of the Collections API to support generics). With generics, the compiler can now detect type-safety violations. Examine Listing 2.

Listing 2 AfterGenerics.java

// AfterGenerics.java

import java.util.*;

public class AfterGenerics
{
  public static void main (String [] args)
  {
   List<Double> l = new ArrayList<Double> ();

   l.add (101.0);
   l.add (89.0);
   l.add (33.0);

   double avg = calculateAverage (l);
   System.out.println ("Average = " + avg);

   l.add ("Average");
   avg = calculateAverage (l);
   System.out.println ("Average = " + avg);
  }

  static double calculateAverage (List<Double> l)
  {
   double sum = 0.0;
   Iterator<Double> iter = l.iterator ();
   while (iter.hasNext ())
     sum += iter.next ();

   return sum / l.size ();
  }
}

Although Listing 2 is similar to Listing 1, there are fundamental differences. For example, List<Double> l = new ArrayList<Double> (); replaces List l = new ArrayList ();. Specifying Double between angle brackets tells the compiler that l references a homogeneous list of Double objects—Double is the element type.

It is necessary to specify <Double> after both List and ArrayList to prevent non-Double objects from being stored in the list, in calculateAverage()’s parameter list to prevent this method from being able to store non-Doubles in the list, and after Iterator to eliminate a (Double) cast when retrieving objects from the list.

Along with four instances of <Double> that provide type information to the compiler, Listing 2 also uses autoboxing to simplify the code. For example, the compiler uses autoboxing with this type information to expand l.add (101.0); to l.add (new Double (101.0));, and to expand sum += iter.next (); to sum += ((Double) iter.next ()).doubleValue ();.

Because the compiler uses the extra type information provided by <Double> to verify that the list can only contain Doubles, the (Double) cast is no longer needed (although it can be specified). Eliminating this cast reduces source code clutter. Furthermore, this type information aids the compiler in detecting attempts to store non-Double objects in the list:

AfterGenerics.java:18: cannot find symbol
symbol : method add(java.lang.String)
location: interface java.util.List<java.lang.Double>
   l.add ("Average");
    ^
1 error

The <Double> specification is an example of generics, a set of language enhancements that promote type safety through generic types and generic methods. The following two sections explore each of these enhancement categories; they provide you with an overview of what generic types and generic methods have to offer.

  • Share ThisShare This
  • Your Account

Discussions

Make a New Comment

You must log in in order to post a comment.

Related Resources

Jennifer  BortelWin FREE iPhone Developer Books and Videos- Introducing @InformIT Giveaways
By Jennifer Bortel on February 5, 2010 No Comments

Apples’s recent iPad announcement made our hearts flutter so we couldn’t resist making an announcement of our own!

Today marks the first ever @InformIT Giveaway!

We’ll regularly post a video like this one profiling spectacular prizes we’re giving away—from books and videos to T-shirts and other exciting stuff. Check out the video below to see the giveaways for today, and then scroll down for more prize details and instructions on how to win them!

Dustin Sullivan"Every OSX developer should have this book on their desk."
By Dustin Sullivan on February 1, 2010 No Comments

That was the sentence Mike Riley ended his recent Dr Dobb's CodeTalk review of Cocoa Programming Developer's Handbook with.

David ChisnallCocoa Tip of the Day, 1/29/10
By David Chisnall on January 29, 2010 No Comments

Don't ignore old versions of OS X.

See All Related Blogs

Informit Network