Home arrow Java arrow Page 5 - Wildcards and Generic Methods in Java
JAVA

Wildcards and Generic Methods in Java


In this part of our continuing discussion of generics in Java, we'll learn how to use wildcards, then move on to generic methods. 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: 5 stars5 stars5 stars5 stars5 stars / 15
May 31, 2007
TABLE OF CONTENTS:
  1. · Wildcards and Generic Methods in Java
  2. · Reading, Writing, and Arithmetic
  3. · Wildcard Type Relationships
  4. · Generic Methods
  5. · Type Inference from Arguments

print this article
SEARCH DEVARTICLES

Wildcards and Generic Methods in Java - Type Inference from Arguments
(Page 5 of 5 )

In the previous section, we saw a method infer its type from an argument:

  <T> T cache( T entry ) { ... }

But what if there is more than one argument? We saw just that situation in our last snippet, the static generic method max( x, y ). All looks well when we give it two identical types:

  Integer max = MathUtils.max( new Integer(1), new Integer( 2 ) ) ;

But what does it make of the arguments in this invocation?

  MathUtils.max( new Integer(1), new Float( 2 ) ) ;

In this case, the Java compiler does something really smart. It climbs up the argument type parent classes, looking for the nearest common supertype. Java also identifies the nearest common interfaces implemented by both of the types. It identifies that both the Integer and the Float types are subtypes of the Number type. It also recognizes that each of these implements (a certain generic instantiation of) the Comparable interface. Java then effectively makes this combination of types the parameter type of T for this method invocation. The resulting type is, to use the syntax of bounds, Number & Comparable. What this means to us is that the result type T is assignable to anything matching that particular combination of types.

  Number max = MathUtils.max( new Integer(1), new Float( 2 ) );
 
Comparable max = MathUtils.max( new Integer(1), new Float( 2 ) );

In English, this statement says that we can work with our Integer and our Float at the same time only if we think of them as Numbers or Comparables, which makes sense. The return type has become a new type, which is effectively a Number that also implements the Comparable interface.

This same inference logic works with any number of arguments. But to be useful, the arguments really have to share some important common supertype or interface. If they don't have anything in common, the result will be their de facto common ancestor, the Object type. For example, the nearest common supertype of a String and a List is Object along with the Serializeable interface. There's not much a method could do with a type lacking real bounds anyway.

Type Inference from Assignment Context

We've seen a generic method infer its parameter type from its argument types. But what if the type variable isn't used in any of the arguments or the method has no arguments? Suppose the method only has a parametric return type:

  <T> T foo() { ... }

You might guess that this is an error because the compiler would appear to have no way of determining what type we want. But it's not! The Java compiler is smart enough to look at the context in which the method is called. Specifically, if the result of the method is assigned to a variable, the compiler tries to make the type of that variable the parameter type. Here's an example. We'll make a factory for our Trap objects:

  <T> Trap<T> makeTrap() { return new Trap<T>(); }

  // usage
  Trap<Mouse> mouseTrap = makeTrap();
  Trap<Bear> bearTrap = makeTrap();

The compiler has, as if by magic, determined what kind of instantiation of Trap we want based on the assignment context.

Before you get too excited about the possibilities, there's not much you can do with a plain type parameter in the body of that method. For example, we can't create instances of any particular concrete type T, so this limits the usefulness of factories. About all we can do is the sort of thing shown here, where we create instances of generics parameterized correctly for the context.

Furthermore, the inference only works on assignment to a variable. Java does not try to guess the parameter type based on the context if the method call is used in other ways, such as to produce an argument to a method or as the value of a return statement from a method. In those cases, the inferred type defaults to type Object. (See the section "Explicit Type Invocation" for a solution.)

Please check back next week for the conclusion to this article.


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

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