Saturday, April 14, 2007

Generics in Java

Generics are about abstraction. Generics let you create classes and methods that work in the same way on different types of objects.

Array types in Java have an inheritance relationship that allows this kind of aliasing to occur:

Date [ ] dates = new Date[10];
Object [ ] objects = dates;
objects[0] = "not a date"; // Runtime ArrayStoreException;


However, arrays have runtime representations as different classes and they check themselves at runtime, throwing an ArrayStoreException in just this case. So, in theory, Java code is not guaranteed typesafe by the compiler if you use arrays in this way.

Why Isn't a List a List<object>"?

The reason gets back to the heart of the rationale for generics that we discussed in the introduction: changing APIs. In the simplest case, supposing an ObjectList type extends a DateList type, the DateList would have all of the methods of ObjectList and we could still insert Objects into it. Now, you might object that generics let us change the APIs, so that doesn't apply anymore. That's true, but there is a bigger problem. If we could assign our DateList to an ObjectList variable, we would have to be able to use Object methods to insert elements of types other than Date into it. We could alias the DateList as an ObjectList and try to trick it into accepting some other type:
    DateList dateList = new DateList( );
ObjectList objectList = dateList;
objectList.add( new Foo( ) ); // should be runtime error!

No comments: