Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed


email article
printer friendly
more resources

Implementing Java Generics
Rough edges aside, see how the addition of Java Generics adds substantial expressive power to the Java programming language
by Klaus Kreft and Angelika Langer

Posted March 10, 2004

Editor's Note: This is the second of two installments presenting an overview of Java Generics, a new language feature that will be supported in the upcoming release of Java 2 Platform, Standard Edition 1.5. The first installment—"Language Features of Java Generics," Java Pro Online, March 3, 2004—discussed Java collections and generic treatment of types and classes. This concluding installment will look at generic treatment of methods as well as implementation and use of Java Generics.

Types aren't the only components that can be parameterized. In addition to generic classes and interfaces, we can define generic methods. Static and nonstatic methods as well as constructors can be parameterized in pretty much the same way as we described parameterizing types previously (see "Language Features of Java Generics," Java Pro Online, March 3, 2004). The syntax is a little different, as you'll see. Everything said about type variables of parameterized types applies to type variables of parameterized methods in the exact same way. See Listing 1 for an example of a parameterized static method: max().

ADVERTISEMENT

Parameterized methods are invoked like regular nongeneric methods. The type parameters are inferred from the invocation context. In our example, the compiler would invoke max<Byte>() automatically. The type inference algorithm is significantly more complex than this simple example suggests, and exhaustive coverage of type inference is beyond the scope of this discussion.

For the sake of completeness let's touch briefly on wildcards. So far we have been instantiating parameterized types using a concrete type that replaces the type parameter in the instantiation. In addition, so-called wildcards can be used to instantiate a parameterized type. A wildcard instantiation looks like this:

List<? extends Number> ref = 
  new LinkedList<Integer>();

In this statement List<? extends Number> is a wildcard instantiation, while LinkedList<Integer> is a regular instantiation. There are three types of wildcards: "? extends Type", "? super Type", and "?". Each wildcard denotes a family of types. The "? extends Number" wildcard, for instance, is the family of subtypes of type Number; "? super Integer" is the family of supertypes of type Integer; and "?" is the set of all types. Correspondingly, the wildcard instantiation of a parameterized type stands for a set of instantiations; for example, List<? extends Number> refers to the set of instantiations of List for types that are subtypes of Number.

Wildcard instantiations can be used for declaration of reference variables, but they cannot be used for creation of objects. Reference variables of a wildcard instantiation type can refer to an object of a compatible type, however. Compatible in this sense are concrete instantiations from the family of instantiations denoted by the wildcard instantiation. In a way, this is similar to interfaces: we cannot create objects of an interface type, but a variable of an interface type can refer to an object of a compatible type, and by "compatible" we mean a type that implements the interface.

Similarly, we cannot create objects of a wildcard instantiation type, but a variable of the wildcard instantiation type can refer to an object of a compatible type—"compatible" meaning a type from the corresponding family of instantiations. Access to an object through a reference variable of a wildcard instantiation type is restricted. Through a wildcard instantiation with "extends" we must not invoke methods that take arguments of the type that the wildcard stands for:

List list = 
  new LinkedList<Integer>();
list.add(new Integer(25)); 
  // compile-time error

The add() method of type List takes an argument of the element type, which is the type parameter of the parameterized List type. Through a wildcard instantiation such as List<? extends Number> it is not permitted to invoke the add() method. Similar restrictions apply to wildcards with "super"; methods where the return type is the type that the wildcard stands for are prohibited. And both restrictions apply for reference variables with a "?" wildcard.




Back to top












Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
| | Discussions | Newsletters | FTPOnline Home