Home arrow Java arrow Generics and Relationships in Java
JAVA

Generics and Relationships in Java


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.

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 5
May 17, 2007
TABLE OF CONTENTS:
  1. · Generics and Relationships in Java
  2. · Parameterized Type Relationships
  3. · Casts
  4. · Writing Generic Classes
  5. · Writing Generic Classes

print this article
SEARCH DEVARTICLES

Generics and Relationships in Java
(Page 1 of 5 )

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.


blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials