Generics and Relationships in Java
(Page 1 of 5 )
Last week we began our discussion of generics in Java. This week we will delve into relationships. This article was excerpted from chapter eight of the book
Learning Java, third edition, written by Patrick Niemeyer and Jonathan Knudsen (O'Reilly; ISBN: 0596008732). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.
Raw Types
Although the compiler treats different parameterizations of a generic type as truly different types (with different APIs) at compile time, we have seen that only one real type exists at runtime. For example, the class of List<Date> and List<String> share the plain old Java class List. List is called the raw type of the generic class. Every generic has a raw type. It is the degenerate, "plain" Java form in which all of the generic type information has been removed and the type variables replaced by some general Java type like Object.
Java 5.0 has been carefully arranged such that the raw type of all of the generic classes works out to be exactly the same as the earlier, nongeneric types. So the raw type of a List in Java 5.0 is the same as the old, nongeneric List type that has been around since JDK 1.2. Since the vast majority of current Java code in existence today does not (and may never) use generics, this type equivalency and compatibility is very important.
It is still possible to use raw types in Java 5.0 just as before. The only difference is that the Java 5.0 compiler generates a new type of warning wherever they are used in an "unsafe" way. For example:
// nongeneric Java code using the raw type, same as always
List list = new ArrayList(); // assignment ok
list.add("foo"); // unchecked warning on usage of raw type
This snippet uses the raw List type just as any good old-fashioned Java code prior to Java 5.0 would have. The difference is that now the Java compiler issues an unchecked warning about the code if we attempt to insert an object into the list.
% javac MyClass.java
Note: MyClass.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
The compiler instructs us to use the -Xlint:unchecked option to get more specific information about the locations of unsafe operations:
% javac -Xlint:unchecked MyClass.java warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.
List: list.add("foo");
Note that creating and assigning the raw ArrayList do not generate a warning. It is only when we try to use an "unsafe" method (one that refers to a type variable) that we get the warning. This means that it's still okay to use older style nongeneric Java APIs that work with raw types. We only get warnings when we do something unsafe in our own code.
One more thing about erasure before we move on. In the previous examples, the type variables were replaced by the Object type, which could represent any type applicable to the type variable E. Later we'll see that this is not always the case. We can place limitations or bounds on the parameter types, and, when we do, the compiler can be more restrictive about the erasure of the type. We'll explain in more detail later after we discussed bounds, but, for example:
class Bounded< E extends Date > {
public void addElement( E element ) { ... }
}
This parameter type declaration says that the element type E may be any subtype of the Date type. In this case, the erasure of the addElement() method can be more restrictive than Object, and the compiler uses Date:
public void addElement( Date element ) { ... }
Date is called the upper bound of this type, meaning that it is the top of the object hierarchy here and the type can be instantiated only on type Date or on "lower" (more derived) types.
Now that we have a handle on what generic types really are, we can go into a little more detail about how they behave.
Next: Parameterized Type Relationships >>
More Java Articles
More By O'Reilly Media
|
This article was excerpted from chapter eight of the book Learning Java, third edition, written by Patrick Niemeyer and Jonathan Knudsen (O'Reilly; ISBN: 0596008732). Check it out today at your favorite bookstore. Buy this book now.
|
|