Angelika Langer - Training & Consulting
HOME | COURSES | TALKS | ARTICLES | GENERICS | LAMBDAS | IOSTREAMS | ABOUT | NEWSLETTER | CONTACT | Twitter | Lanyrd | Linkedin
Books  
HOME 

GENERICS
  FAQ    
    CONTENT
    FUNDAMENTALS
    FEATURES
    PRACTICAL
    TECHNICAL
    INFORMATION
    GLOSSARY
    INDEX
    PDF VERSION
 
LAMBDAS 
IOSTREAMS 
ABOUT 
NEWSLETTER 
CONTACT 
Java Generics FAQs - Programming With Java Generics

This is a collection of answers to frequently asked questions (FAQs) about Java Generics, a new language feature added to the Java programming language in version 5.0 of the Java Standard Edition (J2SE 5.0).

If you want to provide feedback or have any questions regarding Java generics, to which you cannot find an answer in this document, feel free to send me EMAIL or use the GENERICS FAQ form.
A printable version of the FAQ documents is available in PDF format (4.5MB).

Java Generics FAQs - Programming With Java Generics

Practicalities - Programming With Java Generics

© Copyright 2004-2011 by Angelika Langer.  All Rights Reserved.
Using Generic Types Using Generic Methods Coping With Legacy Defining Generic Types and Methods Designing Generic Methods Working With Generic Interfaces Implementing Infrastructure Methods Using Runtime Type Information Reflection

Programming With Generics


 

Using Generic Types and Methods

Should I prefer parameterized types over raw types?

Yes, using parameterized types has various advantages and is recommended, unless you have  a compelling reason to prefer the raw type.
It is permitted to use generic types without type arguments, that is, in their raw form. In principle, you can entirely ignore Java Generics and use raw types throughout your programs.  It is, however, recommended that type arguments are provided when a generic type is used, unless there is a compelling reason not to do so. 

Providing the type arguments rather than using the raw type has a couple of advantages: 

  • Improved readability.   An instantiation with type arguments is more informative and improves the readability of the source code.
  • Better tool support . Providing type arguments enables development tools to support you more effectively: IDEs (= integrated develepment environments) can offer more precise context-sensitive information; incremental compilers can flag type errors the moment you type in the incorrect source code.  Without providing type arguments the errors would  go undetected until you start testing your program. 
  • Fewer ClassCastExceptions.     Type arguments enable the compiler to perform static type checks to ensure type safety at compile time, as opposed to dynamic type checks performed by the virtual machine at runtime.  As a result there are fewer opportunities for the program to raise a ClassCastException .
  • Fewer casts. More specific type informations is available when type arguments are provided, so that hardly any casts are needed compared to the substantial number of casts that clutter the source code when raw types are used.
  • No unchecked warnings.  Raw types lead to "unchecked" warning, which can be prevented by use of type arguments.
  • No future deprecation. The Java Language Specification states that raw types might be deprecated in a future version of Java, and might ultimately be withdrawn as a language feature.
Raw types have an advantage, too: 
  • Zero learning effort. If you ignore Java Generics and use raw types everywhere in you program you need not familiarize yourself with new language features or learn how to read any puzzling error messages.
Advantages that are no advantages: 
  • Improved Performance .  Especially C++ programmers might expect that generic programs are more efficient than non-generic programs, because C++ templates can boost runtime efficiency.  However, if you take a look under the hood of the Java compiler and study how the compiler translates generic source code to byte code you realize that Java code using parameterized types does not perform any faster than non-generic programs. 
LINK TO THIS Practicalities.FAQ001
REFERENCES How does the compiler translate Java generics?
What is an "unchecked" warning?
What is the benefit of using Java generics?

Why shouldn't I mix parameterized and raw types, if I feel like it?
 
Because it is poor style and highly confusing to readers of your source code.
Despite of the benefits of parameterized types you might still prefer use of raw types over using pre-defined generic types in their parameterized form, perhaps because the raw types look more familiar. To some extent it is a matter of style and taste and both styles are permitted.  No matter what your preferences are: be consistent and stick to it.  Either ignore Java generics and use raw type in all places, or take advantage of the improved type-safety and provide type arguments in all places. Mixing both styles is confusing and results in "unchecked" warnings that can and should be avoided. 

Naturally, you have to mix both styles when you interface with source code that was written before the advent of Java generics. In these cases you cannot avoid the mix and the inevitable "unchecked" warnings. However, one should never have any "unchecked" warnings in code that is written in generic style and does not interface with non-generic APIs. 

Here is a typical beginner's mistake for illustration. 

Example (of poor programming style): 

List <String> list = new ArrayList <String> ();
Iterator iter = list.iterator(); 
String s = (String) iter.next();
...
Beginners often start out correctly providing type arguments and suddenly forget, in the heat of the fighting, that methods of parameterized types often return other parameterized types.  This way they end up with a mix of generic and non-generic programming style, where there is no need for it.  Avoid mistakes like this and provide type arguments in all places. 

Example (corrected): 

List <String> list = new ArrayList <String> ();
Iterator <String> iter = list.iterator(); 
String s = iter.next();
...
Here is an example of a code snippet that produces avoidable "unchecked" warnings. 

Example (of avoidable "unchecked" warning): 

void f(Object obj) {
  Class type = obj.getClass();
  Annotation a = type.getAnnotation(Documented.class); // unchecked warning
  ...
}


warning: [unchecked] unchecked call to <A>getAnnotation(java.lang.Class<A>) as a member of the raw type java.lang.Class
        Annotation a = type.getAnnotation(Documented.class);
                                         ^
The getClass method returns an instantiation of class Class , namely Class<? extends X> , where X is the erasure of the static type of the expression on which getClass is called. In the example, the parameterization of the return type is ignored and the raw type Class is used instead.  As a result, certain method calls, such as the invocation of getAnnotation , are flagged with an "unchecked" warning. 

In general, it is recommended that type arguments are provided unless there is a compelling reason not to do so.  In case of doubt, often the unbounded wildcard parameterized type is the best alternative to the raw type.  It is sematically equivalent, eliminates "unchecked" warnings and yields to error messages if their use is unsafe. 

Example (corrected): 

void f(Object obj) {
  Class <?> type = obj.getClass();
  Annotation a = type.getAnnotation(Documented.class); 
  ...
}
LINK TO THIS Practicalities.FAQ002
REFERENCES What is the benefit of using Java generics?
What does type-safety mean?
What is an "unchecked" warning?
What is the raw type?
What is a parameterized or generic)type?
How is a generic type instantiated?
What is an unbounded wildcard parameterized type?

Should I use the generic collections or stick to the old non-generic collections?
 
Provide type arguments when you use collections; it improves clarity and expressiveness of your source code.
The JDK collection framework has been re-engineered. All collections are generic types since Java 5.0.  In principle, you can choose whether you want to use the pre-defined generic collections in their parameterized or raw form.  Both is permitted, but use of the parameterized form is recommended because it improves the readability of your source code. 

Let us compare the generic and non-generic programming style and see how they differ. 

Example (of non-generic style): 

    final class HtmlProcessor {
        public static Collection process( Collection files) {
            Collection imageFileNames = new TreeSet();
            for (Iterator i = files.iterator(); i.hasNext(); ) {
                URI uri = (URI) i.next();
                Collection tokens = HtmlTokenizer.tokenize(new File(uri));
                imageFileNames.addAll(ImageCollector.collect(tokens));  // unchecked warning
            }
            return imageFileNames;
        }
    }
    final class ImageCollector {
        public static Collection collect( Collection tokens) {
            Set images = new TreeSet();
            for (Iterator i = tokens.iterator(); i.hasNext(); ) {
                HtmlToken tok = (HtmlToken) i.next();
                if (tok.getTag().3("img") && tok.hasAttribute("src"))  {
                    Attribute attr = tok.getAttribute("src");
                    images.add(attr.getValue());       // unchecked warning
                } 
            }
            return images;
        }
    }

From the code snippet above it is relatively difficult to tell what the various collections contain.  This is typical for non-generic code.  The raw type collections do not carry information regarding their elements.  This lack of type information also requires that we cast to the alledged element type each time an element is retrieved from any of the collections.  Each of these casts can potentially fail at runtime with a ClassCastException . ClassCastException s are a phenomenon typical to non-generic code. 

If we translate this non-generic source code with a Java 5.0 compiler, we  receive "unchecked" warnings when we invoke certain operations on the raw type collections.  We would certainly ignore all these warnings, or suppress them with the SuppressWarnings annotation. 

Example (of generic counterpart): 

    final class HtmlProcessor {
        public static Collection<String> process( Collection<URI> files) {
            Collection<String> imageFileNames = new TreeSet<String>();
            for (URI uri : files) {
                Collection<HtmlToken> tokens = HtmlTokenizer.tokenize(new File(uri));
                imageFileNames.addAll(ImageCollector.collect(tokens));
            }
            return imageFileNames;
        }
    }
    final class ImageCollector { 
        public static Collection<String> collect( Collection<HtmlToken> tokens) {
            Set<String> images = new TreeSet<String>();
            for (HtmlToken tok : tokens) {
                if (tok.getTag().equals("img") && tok.hasAttribute("src"))  {
                    Attribute attr = tok.getAttribute("src");
                    images.add(attr.getValue());
                } 
            }
            return images;
        }
    }

From the generic source code we can easily tell what type of elements are stored in the various collections. This is one of the benefits of generic Java: the source code is substantially more expressive and captures more of the programmer's intent. In addition it enables the compiler to perform lots of type checks at compile time that would otherwise be performed at runtime.  Note that we got rid of all casts. As a consequence there will be no runtime failure due to a ClassCastException

This is a general rule in Java 5.0:  if your source code compiled without any warnings then there will be no unexpected ClassCastException s at runtime. Of course, if your code contains explicit cast expressions any exceptions resulting from these casts are not considered unexpected.  But the number of casts in your source code will drop substantially with the use of generics. 
 

LINK TO THIS Practicalities.FAQ003
REFERENCES package java.util
Should I prefer parameterized types over raw types?
What is the benefit of using Java generics?
What is an "unchecked" warning?
How can I disable or enable unchecked warnings?
What is the SuppressWarnings annotation?
What is the raw type?
What is a parameterized or generic type?
How is a generic type instantiated?

What is a checked collection?
 
A view to a regular collection that performs a runtime type check each time an element is inserted.
Despite of all the type checks that the compiler performs based on type arguments in order to ensure type safety it is still possible to smuggle elements of the wrong type into a generic collection.  This can happen easily when generic and non-generic code is mixed. 

Example (of smuggling an alien into a collection): 

class Legacy {
  public static List create() {
    List rawList = new ArrayList();
    rawList.add("abc");    // unchecked warning
    ...
    return rawList;
  }
  public static void insert(List rawList) {
    ... 
    rawList.add(new Date ()); // unchecked warning
    ...
  }
}
class Modern {
  private void someMethod() {
    List< String > stringList = Legacy.create();  // unchecked warning
    Legacy.insert(stringList); 
    Unrelated.useStringList(stringList);
  }
}
class Unrelated {
  public static void useStringList(List<String> stringList) {
    ...
    String s = stringList.get(1);   // ClassCastException
    ...
  }
}
An "alien" Date object is successfully inserted into a list of strings.  This can happen inadvertantly when a parameterized type is passed to a piece of legacy code that accepts the corresponding raw type and then adds alien elements.  The compiler can neither detect nor prevent this kind of violation of the type safety, beyond issuing an "unchecked" warning when certain methods of the raw type are invoked. The inevitable type mismatch will later show up in a potentially unrelated part of the program and will mainfest itself as an unexpected ClassCastException

For purposes of diagnostics and debugging JDK 5.0 adds a set of &ldquo;checked&rdquo; views to the collection framework (see java.util.Collections ), which can detect the kind of problem explained above.  If a checked view is used instead of the original collection then the error is reported at the correct location, namely when the "alien" element is inserted. 

Example (of using a checked collection): 

class Legacy {
  public static List create() {
    List rawList = new ArrayList();
    rawList.add("abc");    // unchecked warning
    ...
    return rawList;
  }
  public static void insert(List rawList) {
    ... 
    rawList.add(new Date());    // ClassCastException
    ...
  }
}
class Modern {
  private void someMethod() {
    List<String> stringList 
      = Collections.checkedList (L egacy.create() ,String.class) ; // unchecked warning
    Legacy.insert(stringList);
    Unrelated.useStringList(stringList);
  }
}
class Unrelated
  public static void useStringList(List<String> stringList) {
    ...
    String s = stringList.get(1); 
    ...
  }
}
The checked collection is a view to an underlying collection, similar to the unmodifiable and synchronized views provided by class Collections . The purpose of the checked view is to detect insertion of "aliens" and prevent it by throwing a ClassCastException in case the element to be inserted is of an unexptected type.  The expected type of the elements is provided by means of a Class object when the checked view is created. Each time an element is added to the checked collection a runtime type check is performed to make sure that element is of an acceptable type.  Here is a snippet of the implementation of  the checked view for illustration. 

Example (excerpt from a checked view implementation): 

public class Collections { 
  public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type ) {
    return new CheckedCollection<E>(c, type);
  }
  private static class CheckedCollection<E> implements Collection<E> {
    final Collection<E> c;
    final Class<E> type;

    CheckedCollection(Collection<E> c, Class<E> type) {
      this.c = c;
      this.type = type;
    }
    public boolean add(E o){
      if (! type.isInstance (o))
        throw new ClassCastException();
      return c.add(o);
    }
  }
}

The advantage of using a checked view is that the error is reported at the correct location. The downside of using a checked collection is the performance overhead of an additional dynamic type check each time an element is inserted into the collection. 

The error detection capabilities of the checked view are somewhat limited.  The type check that is performed when an element is inserted into a checked collection is performed at runtime - using the runtime type representation of the expected element type.  If the element type is a parameterized type the check cannot be exact, because only the raw type is available at runtime.  As a result, aliens can be inserted into a checked collection, although the checked collection was invented to prevent exactly that. 

Example (of limitations of checked collections): 

class Legacy {
  public static List legacyCreate() {
    List rawList = new ArrayList();
    rawList.add(new Pair("abc","xyz"));  // unchecked warning
    ...
    return rawList;
  }
  public static void legacyInsert(List rawList) {
    ... 
    rawList.add(new Pair(new Date(),"Xmas") );        // unchecked warning
    ...
  }
}
class Modern {
  private void someModernMethod() {
    List< Pair<String,String> > stringPairs 
      = Collections.checkedList( legacyCreate() ,Pair.class) ; // unchecked warning
    Legacy.insert(stringPairs); 
    Unrelated.useStringPairs(stringPairs);
  }
}
class Unrelated {
  public static void useStringPairs(List<Pair<String,String>> stringPairList) {
    ...
    String s = stringPairList.get(1).getFirst(); // ClassCastException
    ...
  }
}
The checked view can only check against the raw type Pair and cannot prevent that an alien pair of type Pair<Date,String> is inserted into the checked view to a collection of Pair<String,String> .  Remember, parameterized types do not have an exact runtime type representation and there is not class literal for a parameterized type that we could provide for creation of the checked view. 

Note, that a checked view to a collection of type Pair<String,String> cannot be created without a warning. 

Example: 

Lis t<Pair<String,String>> stringPairs 
      = Collections.checkedList
        (new ArrayList< Pair<String,String> > () , Pair .class); // error

Lis t<Pair<String,String>> stringPairs 
      = Collections.checkedList
        ( (List<Pair>) (new ArrayList< Pair<String,String> > ()) , Pair .class); // error

Lis t<Pair<String,String>> stringPairs 
      = Collections.checkedList
        ( (List) (new ArrayList< Pair<String,String> > ()) , Pair .class); // unchecked warning

We cannot create a checked view to a parameterized type such as List<Pair<String,String>> , because it is required that we supply the runtime type representation of the collection's element type as the second argument to the factory method Collections.checkedList .  The element type Pair<String,String> does not have a runtime type representation of its own; there is no such thing as Pair<String,String>.class .  At best, we can specify the raw type Pair as the runtime type representation of the collection's element type.  But this is the element type of a collection of type List<Pair> , not of a List<Pair<String,String>>

This explains why we have to add a cast.  The natural cast would be to type List<Pair> , but the conversion from ArrayList<Pair<String,String>> to List<Pair> is not permitted. These two types a inconvertible because they are instantiations of the same generic type for different type arguments. 

As a workaround we resort to the raw type List , because the conversion ArrayList<Pair<String,String>> to List is permitted for reasons of compatibility.  Use of the raw type results in the usual "unchecked" warnings.  In this case the compiler complains that we pass a raw type List as the first arguments to the Collections.checkedList method, where actually a List<Pair> is exptected. 

In general, we cannot create a checked view  to an instantiation of a collection whose type argument is a parameterized type (such as List<Pair<String,String>> ). This is only possible using debatable casts, as demonstrated above.  However, it is likely that checked collections are used in cases where generic and non-generic legacy code is mixed, because that is the situation in which alien elements can be inserted into a collection inadvertantly.  In a mixed style context, you might not even notice that you work around some of the compiler's type checks, when you create a checked view, because you have to cope with countless "unchecked" warnings anyway. 

The point to take home is that checked views provide a certain safety net for collections whose element type is a raw type, but fails to provide the same kind of safety for collections whose element type is a parameterized type.

LINK TO THIS Practicalities.FAQ004
REFERENCES class java.util.Collections
What is an "unchecked" warning?
What is the raw type?
What happens when I mix generic and non-generic code?
How do I pass type information to a method so that it can be used at runtime?
How do I perform a runtime type check whose target type is a type parameter?
Why is there no class literal for concrete parameterized types?
How does the compiler translate Java generics?
What is type erasure?
What is the type erasure of a parameterized type? 

What is the difference between a Collection<?> and a Collection<Object>?

Collection<Object> is a heterogenous collection, while Collection<?> is a homogenous collection of elements of the same unknown type.
The type Collection<Object> is a heterogenous collection of objects of different types.  It's a mixed bag and can contain elements of all reference types. 

The type Collection<?> stands for a representative from the family of types that are instantiations of the generic interface Collection , where the type argument is an arbitrary reference type.  For instance, it refers to a Collection<Date> , or a Collection<String> , or a Collection<Number> , or even a Collection<Object>

A Collection<?> is a homogenous collection in the sense that it can only contain elements that have a common unknown supertype, and that unknown supertype might be more restrictive than Object .  If the unknown supertype is a final class then the collection is truly homogenous.  Otherwise, the collection is not really homogenous because it can contain objects of different types, but all these types are subtypes of the unknown supertype. For instance, the Collection<?> might stand for Collection<Number> , which is homogenous in the sense that it contains numbers and not apples or pears, yet it can contain a mix of elements of type Short , Integer , Long , etc. 
 

A similar distinction applies to bounded wildcards, not just the unbounded wildcard " ? ". 

A List<Iterable> is a concrete parameterized type.  It is a mixed list of objects whose type is a subtype of Iterable .  I can contain an ArrayList and a TreeSet and a SynchronousQueue , and so on. 

A List<? extends Iterable> is a wildcard parameterized type and stands for a representative from the family of types that are instantiations of the generic interface List , where the type argument is a subtype of Iterable , or Iterable itself.  Again, the list is truly homogenous if the unknown subtype of Iterable is a final class.  Otherwise, it is a mix of objects with a common unknown supertype and that supertype itself is a subtype of Iterable .  For example, List<? extends Iterable> might stand for List<Set> , which is homogenous in the sense that it contains sets and not lists or queues. Yet the List<Set> can be heterogenous because it might contain a mix of TreeSet s and HashSet s.

LINK TO THIS Practicalities.FAQ005
REFERENCES What is a concrete parameterized type?
What is a wildcard parameterized type?

How do I express that a collection is a mix of objects of different types?

Using wildcard instantiations of the generic collections.
Occasionally, we want to refer to sequences of objects of different types. An example would be a List<Object> or a Object[] . Both denote sequences of objects of arbitrary types, because Object is the supertype of all reference types.

How do we express a sequence of objects not of arbitrary different types, but of different instantiations of a certain generic type? Say, we need to refer to a sequence of pairs of arbitrary elements. We would need the supertype of all instantiations of the generic Pair type. This supertype is the unbounded wildcard instantiation Pair<?,?> . Hence a List<Pair<?,?>> and a Pair<?,?>[] would denote sequences of pairs of different types.
 
of any type of any pair type
collection List<Object> List<Pair<?,?>>
array Object[] Pair<?,?>[]

When we want to refer to a mixed sequence of certain types, instead of all arbitrary types, we use the supertype of those "certain types" to express the mixed sequence. Examples are List<Number> or Number[]. The corresponding mixed sequences of instantiations of a generic type is expressed in a similar way. A mixed sequences of pairs of numbers can be expressed as List<Pair<? extends Number, ? extends Number>> or as Pair<? extends Number, ? extends Number>[] .
of any number type of any type of pair of numbers
collection List<Number> List<Pair<? extends
Number,? extends Number>>
array Number[] Pair<? extends Number,?
extends Number>[] *)
*) Legal as the type of reference variable, but illegal in a new expression.
The array type Pair<? extends Number, ? extends Number>[] needs further explanation. This type would in principle denote a mixed sequence of pairs of different type, but this array type is not overly useful. It can only be used for declaration of reference variables, while it must not appear in new expressions. That is, we can declare reference variables of type Pair<? extends Number, ? extends Number>[] , but the reference can never refer to an array of its type, because no such array can be created.

Example (of illegal array creation):

Pair<? extends Number, ? extends Number>[] makeNumberPairs(int size) {
   return new Pair<? extends Number, ? extends Number>[size]; // error
}


error: generic array creation
return new Pair<? extends Number, ? extends Number>[size];
       ^
By and large an array type such as Pair<? extends Number, ? extends Number>[] is not particularly useful, because it cannot refer to an array of its type. It can refer to an array of the corresponding raw type, i.e. Pair[], or to an array of a non-generic subtype, e.g. Point[] , where Point is a subclass of Pair<Double,Double> for instance. In each of these cases using a reference variable of type Pair<? extends Number, ? extends Number>[] offers
no advantage over using a reference variable that matches the type of the array being refered to. Quite the converse; it is error prone and should be avoided. This rules applies to all array types with a component type that is a concrete or bounded wildcard parameterized type. For details see ParameterizedTypes.FAQ104A and ParameterizedTypes.FAQ307A .

Note that arrays of unbounded wildcard parameterized types do not suffer from this restriction. The creation of an array of an unbounded wildcard parameterized type is permitted, because the unbounded wildcard parameterized type is a so-called reifiable type, so that an array reference variable with an unbounded wildcard parameterized type as its component type, such as Pair<?,?>[] , can refer to an array of its type.

Example (of legal array creation):

Pair<?,?>[] makeNumberPairs(int size) {
   return new Pair<?,?>[size]; // fine
}
LINK TO THIS Practicalities.FAQ006
REFERENCES Can I create an object whose type is a wildcard parameterized type?
Can I create an array whose component type is a wildcard parameterized type?
Why is it allowed to create an array whose component type is an unbounded wildcard parameterized type?
Can I declare a reference variable of an array type whose component type is a concrete parameterized type?
Can I declare a reference variable of an array type whose component type is a bounded wildcard parameterized type?
Can I declare a reference variable of an array type whose component type is an unbounded wildcard parameterized type?
What is a reifiable type?

What is the difference between a Collection<Pair<String,Object>>, a Collection<Pair<String,?>> and a Collection<? extends Pair<String,?>>?

All three types refer to collections that hold pairs where the first part is a String and the second part is of an arbitrary type.  The differences are subtle.
The three parameterized types are relatively similar.  They all refer to collections that hold pairs where the first part is a String and the second part is of an arbitrary type. 

Let us start with a comparison of the two concrete parameterized types Collection<Pair<String,Object>> and Collection<Pair<String,?>> .  The both contain pairs where the first part is a String .  The individual pairs stored in the collection can for instance contain a String and a Date , or a String and an Object , or a String and a String . The difference lies in the types of the pairs that can be added to the two collections.

Example (using a Collection<Pair<String,Object>> ): 

Collection< Pair<String, Object > > c = new ArrayList<Pair<String,Object>>();

c.add(new Pair<String, Date >  ("today", new Date()));    // error: illegal argument type
c.add(new Pair<String, Object >("today", new Date()));    // fine

c.add(new Pair<String, String >("name","Pete Becker"));   // error: illegal argument type
c.add(new Pair<String, Object >( "name","Pete Becker" ));   // fine

The example demonstrates that only pairs of type Pair<String,Object> can be added to a Collection<Pair<String,Object>> .  A Collection<Pair<String,Object>> is a homogenous collections of elements of the same type.  The individual pairs may contain different things, as long as  the type of the pair is Pair<String,Object> .  For instance, a pair may consist of a String and a Date , but it must not be of type Pair<String,Date>

Example (using a Collection<Pair<String,?>> ): 

Collection< Pair<String, ? > > c = new ArrayList<Pair<String,?>>();

c.add(new Pair<String, Date >  ("today", new Date()));    // fine
c.add(new Pair<String, Object >("today", new Date()));    // fine

c.add(new Pair<String, String >("name","Pete Becker"));   // fine
c.add(new Pair<String, Object >( "name","Pete Becker" ));   // fine

The example illustrates that a Collection<Pair<String,?>> accepts all types of pairs as long as the first type argument is String . For instance, a pair of type Pair<String,Date> is accepted. A Collection<Pair<String,?>> is a heterogenous collections of elements of the similar types. 

The key difference between a Collection<Pair<String,Object>> and a Collection<Pair<String,?>> is that the first contains elements of the same type and the latter contains elements of different similar types. 
 
 

The type Collection<? extends Pair<String,?>> is fundamentally different. It is a wildcard parameterized type, not a concrete parameterized type.  We simply do not know what exactly a reference variable of the wildcard type refers to. 

Example (using a Collection<? extends Pair<String,?>> ): 

Collection< ? extends Pair<String, ? > > c = new ArrayList<Pair<String,?>>();

c.add(new Pair<String, Date >  ("today", new Date()));    // error: add method must not be called
c.add(new Pair<String, Object >("today", new Date()));    // error: add method must not be called

c.add(new Pair<String, String >("name","Pete Becker"));   // error: add method must not be called
c.add(new Pair<String, Object >( "name","Pete Becker" ));   // error: add method must not be called

The type Collection<? extends Pair<String,?>> stands for a representative from the family of all instantiations of the generic type Collection where the type argument is a subtype of type Pair<String,?> .   This type family includes members such as Pair<String,String> , Pair<String,Object> , Pair<String,? extends Number> , and Pair<String,?> itself . 

Methods like add must not be invoked through a reference of a wildcard type. This is because the add method takes an argument of the unknown type that the wildcard stands for.  Using the variable c of the wildcard type Collection<? extends Pair<String,?>> , nothing can be added to the collection.  This does not mean that the collection being refered to does not contain anything.  We just do not know what exactly the type if the collection is and consequently we do not know what type of elements it contains.  All we know is that is contains pairs where the first part is a String .  But we do not know of which type the second part of the pair is, or whether or not all pairs are of the same type. 


So far, we've silently assumed that Pair is a final class. What if it has subtypes?  Say, it has a subtype class SubTypeOfPair<X,Y> extends Pair<X,Y>

In that case, a Collection<Pair<String,Object>> may not only contain objects of type Pair<String,Object> , but also objects of type SubTypeOfPair<String,Object>

A Collection<Pair<String,?>> may not only contain objects of different pair types such as Pair<String,Date> and Pair<String,Object> , but also objects of subtypes of those, such as SubTypeOfPair<String,Date> and SubTypeOfPair<String,Object>

The type Collection<? extends Pair<String,?>> stands for a representative from the family of all instantiations of the generic type Collection where the type argument is a subtype of type Pair<String,?> .   This type family is now even larger.  It does not only include members such as Pair<String,String> , Pair<String,Object> , Pair<String,? extends Number> , and Pair<String,?> itself, but also type such as SubTypeOfPair<String,String> , SubTypeOfPair<String,Object> , SubTypeOfPair<String,? extends Number> , and SubTypeOfPair<String,?>
 

LINK TO THIS Practicalities.FAQ006A
REFERENCES What is a bounded wildcard?
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard type?
What is the difference between a Collection<?> and a Collection<Object>?
Which super-subset relationships exist among wildcards?

How can I make sure that a wildcard that occurs repeatedly in the same scope stands for the same type?


In general you can't.
If the same wildcard appears repeatedly, each occurrence of the wildcard stands for a potentially different type. There is no way to make sure that the same wildcard represents the same type. 

Example (using the same wildcard repeatedly):

Pair< ? , ? > couple = new Pair< String , String >("Orpheus","Eurydike");
Pair< ? , ? > xmas   = new Pair< String , Date >("Xmas", new Date(104,11,24));
There is nothing you can do to make sure that a reference variable of type Pair<?,?> represents a pair of elements of the same type. 

Depending on the circumstances there might be work-arounds that achieve this goal. For instance, if the type Pair<?,?>   is the type of a method argument, it might be possible to generify the method to ensure that the method argument is a pair of elements of the same type. 

For instance, the following method 

void someMethod(Pair< ? , ? > pair) { ... }
accepts all types of pairs.  It is mostly equivalent to the following generic method: 
< X , Y > void someMethod(Pair< X , Y > pair) { ... }
In order to make sure that only pairs of elements of the same type are passed to the method, the method can be generified as follows: 
< T > void someMethod(Pair< T , T > pair) { ... }
Now it is guaranteed that the method accepts only pairs of elements of the same type.
LINK TO THIS Practicalities.FAQ007
REFERENCES What is a wildcard parameterized type?
If a wildcard appears repeatedly in a type argument section, does it stand for the same type?

 

Using Generic Methods

Why doesn't method overloading work as I expect it?
 
Because there is only one byte code representation of each generic type or method.
When you invoke an overloaded method and pass an argument to the method whose type is a type variable or involves a type variable, you might observe surprising results.  Let us study an example. 

Example (of invocation of an overloaded method): 

static void overloadedMethod( Object o) {
        System.out.println("overloadedMethod(Object) called");
}
static void overloadedMethod( String s) {
        System.out.println("overloadedMethod(String) called");
}
static void overloadedMethod( Integer i) {
        System.out.println("overloadedMethod(Integer) called");
}

static <T> void genericMethod(T t) {
        overloadedMethod (t) // which method is called? 
}

public static void main(String[] args) {
        genericMethod( "abc" );
}

We have several overloaded versions of a method.  The overloaded method is invoked by a generic method which passes an argument of type  T to the overloaded method.  Eventually the generic method is called and a string is passed as an argument to the generic method. One might expect that inside the generic method the string version of the overloaded method is invoked, because the method argument is a string.  This, however, is wrong.

The program prints:
 

overloadedMethod( Object ) called


How can this happen?  We pass an argument of type  String to the overloaded method and yet the version for type  Object is called. The reason is that the compiler creates only one byte code representation per generic type or method and maps all instantiations of the generic type or method to that one representation. 

In our example the generic method is translated to the following representation:
 

void genericMethod( Object t) {
        overloadedMethod (t)
}


Considering this translation, it should be obvious why the  Object version of the overloaded method is invoked.  It is entirely irrelevant what type of object is passed to the generic method and then passed along to the overloaded method.  We will always observe a call of the  Object version of the overloaded method. 

More generally speaking:  overload resolution happens at compile time, that is, the compiler decides which overloaded version must be called. The compiler does so when the generic method is translated to its unique byte code representation.  During that translation type erasure is performed, which means that type parameters are replaced by their leftmost bound or  Object if no bound was specified.  Consequently, the leftmost bound or Object determines which  version of  an overloaded method is invoked.  What type of object is passed to the method at runtime is entirely irrelevant for overload resolution.



Here is another even more puzzling example.

Example (of invocation of an overloaded method):
 

public final class GenericClass<T> {

    private void overloadedMethod( Collection<?> o) {
        System.out.println(" overloadedMethod (Collection<?>)");
    }
    private void overloadedMethod( List<Number> s) {
        System.out.println(" overloadedMethod (List<Number>)");
    }
    private void overloadedMethod( ArrayList<Integer> i) {
        System.out.println(" overloadedMethod (ArrayList<Integer>)");
    }

    private void method(List<T> t) {
overloadedMethod(t);  // which method is called?
    }

    public static void main(String[] args) {
GenericClass <Integer> test = new  GenericClass < Integer >();
        test.method( new  ArrayList< Integer > () );
    }
}


The program prints:
 

overloadedMethod (Collection<?>)

One might have expected that version for  ArrayList<Integer> would be invoked, but that again is the wrong expectation.  Let us see what the compiler translates the generic class to. 

Example (after type erasure):
 

public final class GenericClass {

    private void overloadedMethod( Collection o) {
        System.out.println(" overloadedMethod (Collection<?>)");
    }
    private void overloadedMethod( List s) {
        System.out.println(" overloadedMethod (List<Number>)");
    }
    private void overloadedMethod( ArrayList i) {
        System.out.println(" overloadedMethod (ArrayList<Integer>)");
    }

    private void method(List t) {
overloadedMethod(t);
    }

    public static void main(String[] args) {
GenericClass test = new  GenericClass ();
        test.method( new  ArrayList () );
    }
}

One might mistakenly believe that the compiler would decide that the  List version of the overloaded method is the best match.  But that would be wrong, of course.  The  List version of the overloaded method was originally a version that takes a  List<Number> as an argument, but on invocation a  List<T> is passed, where  T can be any type and need not be a  Number . Since  T can be any type the only viable version of the overloaded method is the version for  Collection<?> .



Conclusion:
Avoid passing type variables to overloaded methods. Or, more precisely, be careful when you pass an argument to an overloaded method whose type is a type variable or involves a type variable.
LINK TO THIS Practicalities.FAQ050
REFERENCES How does the compiler translate Java generics?
What is type erasure?
What is method overriding?
What is method overloading?
What is a method signature?
What is the @Override annotation?
What are override-equivalent signatures?
When does a method override its supertype's method?
What is overload resolution?

Why doesn't method overriding work as I expect it?
 
Because the decision regarding overriding vs. overloading is based on the generic type, not on any instantiation thereof.
Sometimes, when you believe you override a method inherited from a supertype you inadvertantly overload instead of override the inherited method.  This can lead to surprising effects.  Let us study an example.

Example (of overloading):
 

class Box <T> {
  private T theThing;
  public Box(
T t)        { theThing = t; }
  public void reset(
T t) { theThing = t; }
  ...
}
class WordBox< S extends CharSequence > extends Box< String > {
  public WordBox(
S t)    { super(t.toString().toLowerCase()); }
  public void reset(
S t) { super.reset(t.toString().toLowerCase()); } 
  ...
}
class Test {
    public static void main(String[] args) {
        WordBox<String> city = new WordBox<String>("Skogland");
        city.reset("Stavanger"); 
// error: ambiguous
    }
}

error: reference to reset is ambiguous, 
both method reset
(T) in Box<String> and method reset(T) in  WordBox<String> match
        city.reset("Stavanger");
            ^

In this example, one might be tempted to believe that the method  WordBox<String>.reset(String) overrides the superclass method  Box<String>.reset(String) .  After all, both methods have the same name and the same parameter types.  Methods with the same name and the same parameter types in a super- and a subtype are usually override-equivalent.  For this reason, we might expect that the invocation of the  reset method in the  Test class leads to the execution of the  WordBox<String>.reset(String) method.  Instead, the compiler complains about an ambiguous method call.  Why?

The problem is that the subclass's  reset method does not override the superclass's  reset method, but overloads it instead.  You can easily verify this by using the @Override annotation.

Example (of overloading):
 

class Box <T> {
  private T theThing;
  public Box(
T t)        { theThing = t; }
  public void reset(
T t) { theThing = t; }
  ...
}
class WordB ox <S extends CharSequence> extends Box <String> {
  public WordBox(
S t)    { super(t.toString().toLowerCase()); }
@Override 
  public void reset(
S t) { super.reset(t.toString().toLowerCase()); } 
  ...
}


error: method does not override a method from its superclass
        @Override 
         ^


When a method is annotated by an  @Override annotation, the compiler issues an error message if the annotated method does not override any of its supertype's methods.  If it does not override, then it overloads or hides methods with the same name inherited from its supertype.  In our example the  reset method in the generic  WordBox<S extends CharSequence> class overloads the  reset method in the parameterized  Box<String> class.

The overloading happens because the two methods have different signatures. This might come as a surprise, especially in the case of the instantation  WordBox<String> , where the two  reset methods have the same name and the same parameter type. 

The point is that the compiler decides whether a subtype method overrides or overloads a supertype method when it compiles the generic subtype, independently of any instantiations of the generic subtype.  When the compiler compiles the declaration of the generic  WordBox<S extends CharSequence>  class, then there is no knowledge regarding the concrete type by which the type parameter  S might later be replaced.  Based on the declaration of the generic subtype the two  reset methods have different signatures, namely  reset(String) in the supertype and  reset(S_extends_CharSequence) in the generic subtype. These are two completely different signatures that are not override-equivalent.  Hence the compiler considers them overloading versions of each other.

In a certain instantiation of the subtype, namely in  WordBox<String> , the type parameter  S might be replaced by the concrete type String.   As a result both  reset methods visible in  WordBox<String> suddenly have the same argument type.  But that does not change the fact that the two methods still have different signatures and therefore overload rather than override each other.

The identical signatures of the two overloading version of the  reset method that are visible in  WordBox<String>  lead to the anbiguitiy that we observe in our example. When the  reset method is invoked through a reference of type  WordBox<String> , then the compiler finds both overloading versions.  Both versions are perfect matches, but neither is better than the other, and the compiler rightly reports an ambiguous method call.



Conclusion:
Be careful when you override methods, especially when generic types or generic methods are involved.  Sometimes the intended overriding turns out to be considered overloading by the compiler, which leads to surprising and often confusing results.  In case of doubt, use the  @Override annotation.
LINK TO THIS Practicalities.FAQ051
REFERENCES How does the compiler translate Java generics?
What is type erasure?
What is method overriding?
What is method overloading?
What is a method signature?
What is the @Override annotation?
When does a method override its supertype's method?
Can a method of a generic subtype override a method of a generic supertype?

Coping With Legacy

What happens when I mix generic and non-generic legacy code?
 
The compiler issues lots of "unchecked" warnings.
It is permitted that a generic class or method is used in both its parameterized and its raw form.  Both forms can be mixed freely.  However, all uses that potentially violate the type-safety are reported by means of an "unchecked warning".  In practice, you will see a lot of unchecked warnings when you use generic types and methods in their raw form. 

Example (of mixing paramterized and raw use of a generic type): 

interface Comparable<T> {
  int compareTo(T other);
}
class SomeClass implements Comparable {
  public int compareTo(Object other) {
    ...
  }
}
class Test {
  public static void main(String[] args) {
    Comparable x = new SomeClass();
    x.compareTo(x);     // "unchecked" warning
  }
}


warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
        x.compareTo(x);
                   ^
The Comparable interface is a generic type.  Its raw use in the example above leads to "unchecked" warnings each time the compareTo method is invoked. 

The warning is issued because the method invocation is considered a potential violation of the type-safety guarantee.  This particular invocation of compareTo is not unsafe, but other methods invoked on raw types might be. 

Example (of type-safety problem when mixing parameterized and raw use): 

class Test {
  public static void someMethod( List list) {
    list.add("xyz");     // "unchecked" warning
  }
  public static void test() {
    List<Long> list = new ArrayList<Long> ();
    someMethod(list);
  }
}


warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
     list.add("xyz");
             ^
Similar to the previous example, the invocation of the add method on the raw type List is flagged with an "unchecked" warning.  The invocation is indeed unsafe, because it inserts a string into a list of long values. 

The compiler cannot distinguish between invocations that are safe and those that are not.  It reports "unchecked" warnings just in case that a call might be unsafe.  It applies a simple rule: every invocation of a method of a raw type that takes an argument of the unknown type that the class's type parameter stands for, is potentially unsafe.  That does not mean, it must be unsafe (see Comparable.compareTo ), but it can be unsafe (see List.add ). 

If you find that you must intermix legacy and generic code, pay close attention to the unchecked warnings. Think carefully how you can justify the safety of the code that gives rise to the warning. Once you've made sure the warning is harmless suppress it using the SuppressWarnings annotation. 

If you can re-engineer existing code or if you write new code from scratch you should use generic types and methods in their parmeterized form and avoid any raw use.  For instance, the examples above can be "repaired" as follows: 

Example #1 (corrected): 

interface Comparable<T> {
  int compareTo(T other);
}
class SomeClass implements Comparable <Object> {
  public int compareTo(Object other) {
    ...
  }
}
class Test {
  public static void main(String[] args) {
    Comparable <Object> x = new SomeClass();
    x.compareTo(x);     // fine
  }
}
No "unchecked" warning occurs if the Comparable interface is used in its parameterized form in all places. 

Example #2 (corrected): 

class Test {
  public static void someMethod( List <String> list) {
    list.add("xyz");     // fine
  }
  public static void test() {
    List<Long> list = new ArrayList<Long> ();
    someMethod(list);   // error
  }
}


error: someMethod(java.util.List<java.lang.String>) cannot be applied to java.util.List<java.lang.Long>)
        someMethod(list);
        ^
The "unchecked" warning in someMethod is no longer necessary if the generic type List is used in its parameterized form as List<String> .  With this additional type information the compiler is now capable of flagging the formerly undetected type-safety problem in method test as an error.
LINK TO THIS Practicalities.FAQ101
REFERENCES What does type-safety mean?
What is the raw type?
Can I use a raw type like any other type?
What is an "unchecked" warning?
How can I disable or enable unchecked warnings?
What is the SuppressWarnings annotation?

Should I re-engineer all my existing types and generify them?


No, most likely not.
Not all types are inherently generic.  There is no point to turning a type into a generic type if the type does not semantically depend on a particular unknown type that can be more adequately be expressed by means of a type parameter. 

Example (of an arbitrary non-generic type taken from package org.w3c.dom ): 

public interface NameList {
  boolean  contains(String str);
  boolean  containsNS(String namespaceURI, String name);
  int      getLength();
  String   getName(int index);
  String   getNamespaceURI(int index);
}
The NameList interface takes and returns either strings or primitive types and there is no reason why this class should be generic in any form. 

Other non-generic types would benefit from generics. 

Example (of another arbitrary non-generic type): 

public interface Future {
  boolean  cancel(boolean mayInterruptIfRunning);
  Object    get();
  Object    get(long timeout, TimeUnit unit);
  boolean  isCancelled();
  boolean  isDone();
}
This interface has get methods that return Object references.  If these methods return the same type of object for a given instance of type Future , then the interface is more precisely declared as a generic interface. 

Example (of corresponding generic type): 

public interface Future <V> {
  boolean  cancel(boolean mayInterruptIfRunning);
  V         get();
  V         get(long timeout, TimeUnit unit);
  boolean  isCancelled();
  boolean  isDone();
}

Occasionally, the generification of one type leads to the generification of other related types. 

Example (of non-generic types taken from package java.lang.ref in JDK 1.4): 

public class ReferenceQueue {
  public ReferenceQueue() { }
  public Reference poll() { ... }
  public Reference remove(long timeout) 
    throws IllegalArgumentException, InterruptedException { ... }
  public Reference remove() 
    throws InterruptedException { ... } 
}
public abstract class Reference {
  private Object referent; 
  ReferenceQueue queue;
  Reference next;
  Reference( Object referent) { ... }
  Reference( Object referent, ReferenceQueue queue) { ... }
  public void clear() { ... }
  public boolean enqueue() { ... }
  public Object get() { ... }
  public boolean isEnqueued() { ... }
}
The abstract class Reference internally holds a reference of type Object and has methods that take and return Object references.  If these methods take and return the same type of object that is held internally, then the class is more precisely declared as a generic class, namely as Reference<T> where T is the type of the referent.

When we decide to parameterize class Reference then we must provide type arguments in all places where type Reference is used.  This affects class ReferenceQueue because it has methods that return references of type Reference .  Consequently, we would declare class ReferenceQueue as a generic class, too. 

Once we have generified class ReferenceQueue then we must return to class Reference and provide type arguments in all places where type ReferenceQueue is used. 

Example (of corresponding generic type in JDK 5.0): 

public class ReferenceQueue <T> {
  public ReferenceQueue() { }
  public Reference <? extends T> poll() { ... }
  public Reference <? extends T> remove(long timeout) 
    throws IllegalArgumentException, InterruptedException { ... }
  public Reference <? extends T> remove() 
    throws InterruptedException { ... } 
}
public abstract class Reference <T>   {
  private T referent; 
  ReferenceQueue <? super T> queue;
  Reference next;
  Reference( T referent) { ... }
  Reference( T referent, ReferenceQueue <? super T> queue) { ... }
  public void clear() { ... }
  public boolean enqueue() { ... }
  public T get() { ... }
  public boolean isEnqueued() { ... }
}
This is an example where a class, namely ReferenceQueue , is turned into a generic class because the types it uses are generic.  This propagation of type parameters  into related types is fairly common. For instance, the subtypes of type Reference (namely PhantomReference , SoftReference , and WeakReference ) are generic types as well.
LINK TO THIS Practicalities.FAQ102
REFERENCES How do I generify an existing non-generic class?

How do I generify an existing non-generic type or method?
 
There are no carved-in-stone rules.  It all depends on the intended semantics of the generified type or method.
Modifying an existing type that was non-generic in the past so that it becomes usable as a parameterized type in the future is a non-trivial task. The generification must not break any existing code that uses the type in its old non-generic form and it must preserve the original non-generic type's semantic meaning. 

For illustration, we study a couple of examples from the collection framework (see package java.util in J2SE 1.4.2 and J2SE 5.0 ).  We will generify the traditional non-generic interface Collection .  From the semantics of a collection it is obvious that for a homogenous collection of elements of the same type the element type would be the type parameter of a generic Collection interface. 

Example (from JDK 1.4; before generification): 

interface Collection {
  boolean add     ( Object o); 
  boolean contains( Object o);
  boolean remove  ( Object o);
  ...
}
These methods take an element as an argument and insert, find or extract the element from the collection.  In a generic collection the method parameters would be of type E , the interface's type parameter.

Example (from JDK 5.0; after generification): 

interface Collection <E> {
  boolean add     ( E o); 
  boolean contains( E o); 
  boolean remove  ( E o);
  ...
}
However, this modification does not exactly preserve the semantics of the old class.  Before the generification it was possible to pass an arbitrary type of object to these methods.  After the generification only objects of the "right" type are accepted as method arguments. 

Example (of modified semantics): 

class ClientRepository {
  private Collection <Client> clients = new LinkedList<Client>();
  ...
  boolean isClient( Object c) {
    return clients.contains(c);   // error
  } 
}
Passing an Object reference to method contains used to be permitted before the generification, but no longer compiles after generification.    Seemingly, our generified type is not semantically  compatible with the original non-generic type.  A more relaxed generification would look like this.

Example (from JDK 5.0; after an alternative generification): 

interface Collection <E> {
  boolean add     ( E o); 
  boolean contains( Object o); 
  boolean remove  ( Object o);
  ...
}
Only for the add method now would accept the more restrictive method parameter type E .  Since a Collection<E> is supposed to contain only elements of type E , it is expected and desired that insertion of an alien element is rejected at compile time. 

This seemingly trivial example illustrates that decisions regarding a "correct" generification are largely a matter of taste and style. Often, there are several viable approaches for a generification.  Which one is "correct" depends on the specific requirements to and expectations of the semantics of the resulting generified type. 

LINK TO THIS Practicalities.FAQ103
REFERENCES How do I avoid breaking binary compatibility when I generify an existing type or method?

Can I safely generify a supertype, or does it affect all subtypes?
 
Yes, we can generify non-generic legacy supertypes without affecting the non-generic legacy subtypes - provided the subtype method's signature is identical to the erasure of the supertype method's signature.
Assume we have a class hierarchy of legacy types and we want to generify the supertype.  Must we also generify all the subtypes?  Fortunately not. Let us consider an example.

Example (of a hierarchy of legacy types):
 

class Box {
  private Object theThing;
  public Box(Object t)        { theThing = t; }
  public void reset( Object t) { theThing = t; }
  public  Object get()         { return theThing; }
  ...
}
class NamedBox extends Box {
  private String theName;
  public NamedBox(Object t,String n) { super(t); theName = n; }
  public void reset( Object t)        { super.reset(t); }
  public  Object get()                { return super.get(); }
  ...
}

Now we decide to generify the supertype.

Example (same as before, but with generified superclass):
 

class Box <T> {
  private T theThing;
  public Box(T t)        { theThing = t; }
  public void reset( t) { theThing = t; }
  public  get()         { return theThing; }
  ...
}
class NamedBox extends Box {
  private String theName;
  public NamedBox(Object t,String n) { super(t); theName = n; }
  public void reset( Object t)        { super.reset(t); }
  public  Object get()                { return super.get(); }
  ...
}

warning: [unchecked] unchecked call to Box(T) as  a member of the raw type Box
  public NamedBox(Object t,String n) { super(t); theName = n; }
                                            ^
warning: [unchecked] unchecked call to reset(T) a s a member of the raw type Box
  public void reset(Object t)        { super.reset(t); }
                                                  ^


The subclass is still considered a subtype of the now generic supertype where the  reset and  get method override the corresponding supertype methods. Inevitably, we now receive unchecked warnings whenever we invoke certain methods of the supertype because we are now using methods of a raw type. But other than that, the subtype is not affected by the re-engineering of the supertype.  This is possible because the signatures of the subtype methods are identical to the erasures of the signatures of the supertype methods.

Let us consider a slightly different generification.  Say, we re-engineer the superclass as follows.

Example (same as before, but with a different generification):
 

class Box <T> {
  private T theThing;
  public  <S extends T> Box(S t)         { theThing = t; }
  public  <S extends T> void reset( t) { theThing = t; }
  public  T get()  { return theThing; }
  ... 
}
class NamedBox extends Box {
  private String theName;
  public NamedBox(Object t,String n) { super(t); theName = n; }
  public void reset( Object t)        { super.reset(t); }
  public  Object get()                { return super.get(); }
  ...
}

This time the  reset method is a generic method.  Does the subtype method  reset still override the generic supertype method?  The answer is: yes. The subtype method's signature is still identical to the erasure of the supertype method's signature and for this reason the subtype method is considered an overriding method.  Naturally, we still receive the same unchecked warnings as before, but beyond that there is no need to modify the subtype although we re-engineered the supertype.

The point to take home is that methods in a legacy subtype can override (generic and non-generic) methods of a generic supertype as long as the subtype method's signature is identical to the erasure of the supertype method's signature.

LINK TO THIS Practicalities.FAQ103A
REFERENCES Can a method of a non-generic subtype override a method of a generic supertype?
How does the compiler translate Java generics?
What is type erasure?
What is method overriding?
What is a method signature?
What is a subsignature?
What are override-equivalent signatures?
When does a method override its supertype's method?

How do I avoid breaking binary compatibility when I generify an existing type or method?
 
Sometimes a dummy bound does the trick.
Occasionally, one must pay attention to the fact that a generification might change the signature of some methods in the byte code.  Changing the signature will break existing code that cannot be recompiled and relies on the binary compatibility of the old and new version of the .class file. 

Example (before generification, taken from package java.util ): 

class Collections {
  public static Object max( Collection coll) {...} 
  ...
}
The max method finds the largest element in a collection and obviously the declared return type of the method should match the element type of the collection passed to the method.  A conceivable generification could look like this.

Example (after a naive generification): 

class Collections {
  public static <T extends Comparable<? super T>>
  T max(Collection <? extends T> coll)  {...} 
  ...
}
While this generification preserves the semantics of the method, it changes the signature of the max method.  It is now a method with return type Comparable , instead of Object

Example (after type erasure): 

class Collections {
  public static Comparable max( Collection coll)  {...} 
  ...
}
This will break existing code that relies on the binary compatibility of the .class files.  In order to preserve the signature and thus the binary compatibility, an otherwise superfluous bound can be used. 

Example (after binary compatible generification, as available in package java.util ): 

class Collections {
  public stati c <T extends Object & Comparable<? super T>>
  T max(Collection <? extends T> coll)  {...}
  ...
}
The leftmost bound of the type parameter is now type Object instead of type Comparable , so that the type parameter T is replaced by Object during type erasure. 

Example (after type erasure): 

class Collections {
  public static Object max( Collection coll)  {...} 
  ...
}


Afterthought: 

Perhaps you wonder why the hack decribed in this FAQ entry is needed.  Indeed, had the Collections.max method been defined as returning a Comparable in the first place, no further measures, such as adding Object as a type parameter bound, had been required to preserve binary compatibility. Basically, the declared return type Object is a mistake in the design of this method. 

If you carefully study the specification of the Collections.max  method's functionality then you realize that all elements of the collection are required to implement the Comparable interface.  Consequently, the returned object is Comparable , too.  There is no reason why the method should return an Object reference. 

The only explanation one can think of is that in pre-generic Java there was no way of ensuring by compile-time type checks that the Collection contains only Comparable objects.  However, this was ensured via runtime type checks, namely an explicit downcast in the implementation of the method.  Hence this is not really an excuse for the bug. 

Note, that the runtime time type check in the pre-generic version of the Collections.max method still exists in the generic version.  The former explicit cast is now an implicit one generated by the compiler.  In the generic version, this cast can never fail (unless there are unchecked warnings), because the type parameter bound Comparable ensures at compile-time that the elements in the Collection are Comparable .

LINK TO THIS Practicalities.FAQ104
REFERENCES

 
 

Defining Generic Types and Methods

Which types should I design as generic types instead of defining them as regular non-generic types?

Types that use supertype references in several places and where there is a correspondence between the occurrences of these supertypre references. 
Not all types are inherently generic, not even the majority of the types in a program is.  The question is: which types profit from being generic types and which ones do not. This FAQ entry tries to sketch out some guidelines.

Obvious candidates for generic types are those types that work closely with existing generic types.  For instance, when you derive from  a generic type, such as  WeakReference<T> , then the derived class is often generic as well. 

Example (of a generic subclass):
 

class  WeakKey < T> extends java.lang.ref.WeakReference <T> {
  private int hash;
  public WeakKey(
T ref) { super(t); hash = t.hashcode(); }
  ...
  public int hashcode() { return hash; }
}

The subclass  WeakKey can be used in lieu of its superclass  WeakReference and therefore is as generic as the superclass is.

Classes that use generic types are sometimes generic as well. For instance, if you want to build a cache abstraction as a map of a key  and an associated value that is refered to by a soft reference, then this new  Cache type will naturally be a generic type.

Example (of a generic cache):
 

class Cache <K,V> {
  private HashMap<
K ,SoftReference< V >> theCache;
  ...
  public 
V get( K key) { ... }
  public  V put( K key,  V value) { ... }
  ...
}


The  Cache class is built on top of a  Map and can be seen as a wrapper around a  Map and therefore is as generic as the  Map itself.

On the other hand, a cache type need not necessarily be a generic type.  If you know that all keys are strings and you do not want to have different types of caches for different types of cached values, then the  Cache type might be a non-generic type, despite of the fact that it works closely with the generic  Map  type.

Example (of a non-generic cache):
 

class Cache {
  private HashMap< String ,SoftReference< Object >>  theCache ;
  ...
  public  Object get( String , key) { ... }
  public  Object put( String , key,  Object value) { ... }
  ...
}


Both abstractions are perfectly reasonable.  The first one is more flexible.  It includes the special case of a  Cache<String,Object> , which is the equivalent to the non-generic  Cache abstraction.  In addition, the generic  Cache allows for different cache types.  You could have a  Cache<Link,File> , a  Cache<CustomerName,CustomerRecord> , and so on.  By means of the parameterization you can put a lot more information into the type of the cache. Other parts of your program can take advantage of the enhanced type information and can do different things for different types of caches - something that is impossible if you have only one non-generic cache type. 
 

Another indication for a generic type is that a type uses the same supertype in several places.   Consider a Triple class.  Conceptually, it contains three elements of the same type.  It could be implemented as a non-generic class. 

Example (of a non-generic triple): 

class Triple {
  private Object t1, t2, t3;
  public Triple( Object a1,  Object a2,  Object a3) {
    t1 = a1;
    t2 = a2;
    t3 = a3;
  }
  public void reset( Object a1,  Object a2,  Object a3) {
    t1 = a1;
    t2 = a2;
    t3 = a3;
  }
  public void setFirst( Object a1) {
    t1 = a1;
  }
  public void setSecond( Object a2) {
    t2 = a2;
  }
  public void setThird( Object a3) {
    t3 = a3;
  }
  public  Object getFirst() {
    return a1;
  }
  public  Object getSecond() {
    return a2;
  }
  public  Object getThird() {
    return a3;
  }
  ...
}
A triple is expected to contain three elements of the same type, like three strings, or three dates, or three integers.  It is usually not a triple of objects of different type, and its constructors enforce these semantics.  In addition, a certain triple object will probably contain the same type of members during its entire lifetime. It will not contain strings today, and integers tomorrow.  This, however, is not enforced in the implemention shown above, perhaps mistakenly so. 

The point is that there is a correspondence between the types of the three fields and their type  Object does not convey these semantics.  This correspondence - all three fields are of the same type - can be expressed more precisely by a generic type. 

Example (of a generic triple): 

class Triple <T> {
  private T t1, t2, t3;
  public Triple( T a1, T a2, T a3) {
    t1 = a1;
    t2 = a2;
    t3 = a3;
  }
  public void reset( T a1, T a2, T a) {
    t1 = a1;
    t2 = a2;
    t3 = a3;
  }
  public void setFirst( T a1) {
    t1 = a1;
  }
  public void setSecond( T a2) {
    t2 = a2;
  }
  public void setThird( T a3) {
    t3 = a3;
  }
  public T getFirst() {
    return a1;
  }
  public T getSecond() {
    return a2;
  }
  public T getThird() {
    return a3;
  }
  ...
}
Now we would work with a Triple<String> , saying that all members are strings and will remain strings.  We can still permit variations like in a Triple<Number> , where the members can be of differents number types like Long Short and Integer , and where a Short member can be replaced by a Long member or vice versa.  We can even use Triple<Object> , where everything goes.  The point is that the generification allows to be more specific and enforces homogenity.

Conclusion
When a type uses a supertype in several places and there is a correspondence among the difference occurrences, then this is an indication that perhas the type should be generic. 

Note, that the supertype in question need not be  Object .  The same principle applies to supertypes in general.  Consider for instance an abstraction that uses character sequences in its implementation and refers to them through the supertype  CharSequence . Such an abstraction is a candidate for a generic type.

Example (of a non-generic class using character sequences):
 

class  CharacterStore {
  private  CharSequence theChars;
  ...
  public 
CharacterProcessingClass ( CharSequence s) { ... }
  public void set( CharSequence s) { ... }
  public 
CharSequence get() { ... }
  ...
}


The idea of this abstraction is:  whatever the  get method receives is stored and later returned by the  set method.  Again there is a correspondence between the argument type of the  set method, the return type of the  get method, and the type of the private field. If they are supposed to be of  the same type  then the abstraction could be more precisely  expressed as a generic type.

Example (of a generic class using character sequences):
 

class  CharacterStore <C extends CharSequence> {
  private  C theChars;
  ...
  public  CharacterStore ( C s) { ... }
  public void set( s) { ... }
  public 
get() { ... }
  ...
}


This class primarily serves as a store of a character sequence and we can create different types of stores for different types of character sequences, such as  a  CharacterStore <String> or a  CharacterStore <StringBuilder>

If, however, the semantics of the class is different, then the class might be better defined as a non-generic type.  For instance, the purpose might be to provide a piece of functionality, such as checking for a suffix, instead of serving as a container.  In that case it does not matter what type of character sequence is used and a generification would not make sense.

Example (of a non-generic class using character sequences):
 

class  SuffixFinder {
private  CharSequence theChars;
  ...
  public  CharacterProcessingClass ( CharSequence s) { ... }
  public boolean hasSuffix( CharSequence suffix) { ... }
}


In this case, the character sequence being examined could be a  CharBuffer and the suffix to be searched for could be a  StringBuilder , or vice versa.  It would not matter.  There is no correspondence implied between the types of the various character sequences being used in this abstraction.  Under these circumstances, the generification does not provide any advantage.
 

Ultimately, it all depends on the intended semantics, whether a type should be generic or not. Some indicators were illustrated above:  a close relationship to an existing generic type, correspondences among references of the same supertype, the need for distinct types generated from a generic type, and the need for enhanced type information.  In practice, most classes are non-generic, because most classes are defined for one specific purpose and are used in one specific context.  Those classes hardly ever profit from being generic.

LINK TO THIS Practicalities.FAQ201
REFERENCES

Do generics help designing parallel class hierarchies?

Yes.
Some hierarchies of types run in parallel in the sense that a supertype refers to another type and the subtype refers to a subtype of that other type. Here is an example, where the supertype  Habitat refers to  Animal s and the subtype  Aquarium refers to  Fish .
 
Overriding methods in the subtype often have to perform a type checks in this situation, like in the example below.

Example (of parallel type hierarchies leading to dynamic type check):
 

abstract class Habitat {
  protected Collection theAnimals;
  ...
  public void addInhabitant( Animal animal) {
    theAnimals.add(animal);
  }
}
class Aquarium extends Habitat {
  ...
public void addInhabitant( Animal fish) {
    if (fish  instanceof Fish )
      theAnimals.add(fish);
    else
      throw new IllegalArgumentException(fish.toString());
  }
}

Aquarium a = new Aquarium();
a.addInhabitant(new Cat());   //  ClassCastException


In order to ensure that the aquarium only contains fish, the addInhabitant method performs an  instanceof test.  The test may fail at runtime with a  ClassCastException .  It would be nice if the  addInhabitant method could be declared as taking a  Fish argument; the  instanceof test would be obsolete then.  The problem is  that a addInhabitant(Fish) method in the  Aquarium class would be an overloading version of the  Habitat 's  addInhabitant(Animal) method rather than an overriding version thereof and this is neither intended nor corrct.  Hence, we cannot get rid of the  instanceof test - unless we consider generics.

This kind of type relationship among parallel type hierarchies can be more elegantly expressed by means of generics.  If the supertype  Habitat were a generic type, then the subtype  Aquarium would no longer need the type check.  Here is a re-engineered version of the example above.

Example (same as above, re-engineered using generics):
 

abstract class Habitat <A extends Animal> {
  protected Collection <A> theAnimals;
  ...
  public void addInhabitant( A animal) {
    theAnimals.add(animal);
  }
}
class Aquarium extends Habitat <Fish> {
  ...
public void addInhabitant( Fish fish) {
    // no test necessary
    theAnimals.add(fish);
  }
}

Aquarium a = new Aquarium();
a.addInhabitant(new Cat());   //  error: illegal argument type

When the supertype is generic, then the subtype can derive from a certain instantiation of the supertype.  The advantage is that overriding methods in the subtype can now be declared to take the intended type of argument rather than a supertype argument.  In the example, the  Aquarium is a  Habitat<Fish> , which means that the addInhabitant method now takes a  Fish argument instead of an  Animal argument.  This way, the  instanceof test is no longer necessary and any attempt to add a non- Fish to the  Aquarium will be detected at compile-time already.

Note, that the generic version of the type hierarchy has further advantages.

Example (of parallel type hierarchies):
 

abstract class Habitat {
  protected Collection theAnimals;
  ...
  public Habitat( Collection animals) { 
    theAnimals = animals;
  }

}
class Aquarium extends Habitat {
  ...
   public Aquarium( Collection fish) {
// no type check possible
     super(fish);
   }

}

ArrayList animals = new ArrayList();

animals.add(new Cat());
Aquarium a = new Aquarium(animals);  // no error or exception here

In the  Aquarium constructor there is no way to check whether the collection contains  Fish or not.  Compare this to the generic solution.

Example (of parallel type hierarchies using generics):
 

abstract class Habitat<A extends Animal> {
  protected Collection<A> theAnimals;
  ...
  public Habitat(Collection < A> animals) { 
    theAnimals = animals;
  }
}
class Aquarium extends Habitat<Fish> {
  ...
   public Aquarium(Collection <Fish> fish) {
// no type check necessary
     super(fish);
   }
}

ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Cat());
Aquarium a = new Aquarium(animals);  //  error: illegal argument type

In this generic version of the type hierarchy, the  Aquarium constructor requires a  Collection<Fish> as a constructor argument and this collection of fish can be passed along to the supertype's constructor because  Aquarium extends the supertype's instantiation  Habitat<Fish> whose constructor requires exactly that type of collection.

Conclusion:  Type hierarchies that run in parallel are more easily and more reliably implemented by means of generics.

LINK TO THIS Practicalities.FAQ201A
REFERENCES What is method overriding?
What is method overloading?

When would I use an unbounded wildcard parameterized type instead of a bounded wildcard or concrete parameterized type?

When you need a reifiable type.
Occasionally, an unbounded wildcard parameterized type is used because it is a so-called reifiable type and can be used in situations where non-refiable types are not permitted. 
  • One of these situations are type checks (i.e., cast or instanceof expressions).  Non-reifiable types (i.e., concrete or bounded wildcard parameterized type) are not permitted as the target type of a type check or lead to "unchecked" warnings. 
  • Another situation is the use of arrays.  Non-reifiable types (i.e., concrete or bounded wildcard parameterized type) are not permitted as the component type of an array.
Depending on the situation, the unbounded wildcard parameterized type can substitute a concrete or bounded wildcard parameterized type in a type check or an array in order to avoid errors or warning. 

Non-reifiable types (i.e., concrete or bounded wildcard parameterized type) are not permitted as the target type of a type check or lead to "unchecked" warnings. A typical situation, in shich such a cast would be needed, is the implementation of methods such as the equals method, that take Object reference and where a cast down to the actual type must be performed. 

Example (not recommended): 

class Triple<T> {
  private T fst, snd, trd;
    ...
  public boolean equals (Object other) {
    ...
    Triple<T> otherTriple = (Triple<T>) other; // warning; unchecked cast
    return (this.fst.equals(otherTriple.fst)
         && this.snd.equals(otherTriple.snd)
         && this.trd.equals(otherTriple.trd));
  }
}
When we replace the cast to Triple<T> by a cast to Triple<?> the warning disappears, because unbounded wildcard parameterized type are permitted as target type of a cast without any warnings. 

Example (implementation of equals ): 

class Triple<T> {
  private T fst, snd, trd;
    ...
  public boolean equals(Object other) {
    ...
    Triple<?> otherTriple = (Triple<?>) other;
    return (this.fst.equals(otherTriple.fst)
         && this.snd.equals(otherTriple.snd)
         && this.trd.equals(otherTriple.trd));
  }
}
Note, that replacing the concrete parameterized type by the wildcard parameterized type works in this example only because we need no write access to the fields of the referenced object referred and we need not invoke any methods.  Remember, use of the object that a wildcard reference variable refers to is restricted.  In other situations, use of a wildcard parameterized type might not be a viable solution, because full access to the referenced object is needed.  (Such a situation can arise, for instance, when you implement the clone method of a generic class.) 


Non-reifiable types (i.e., concrete or bounded wildcard parameterized type) are not permitted as the component type of an array.  Here is an example: 

Example (of illegal array type): 

static void test() {
  Pair<Integer,Integer>[] arr = new Pair<Integer,Integer>[10] ; // error
  arr[0] = new Pair<Integer,Integer>(0,0);
  arr[1] = new Pair<String,String>("","");      // would fail with ArrayStoreException

  Pair<Integer,Integer> pair = arr[0];
  Integer i = pair.getFirst();
  pair.setSecond(i);
}

The concrete parameterized type Pair<Integer,Integer> is illegal. As a workaround one might consider using an array of the corresponding unbounded wildcard parameterized type. 

Example (of array of unbounded wildcard parameterized type): 

static void test() {
  Pair<?,?>[] arr = new Pair<?,?>[10] ;
  arr[0] = new Pair<Integer,Integer>(0,0);
  arr[1] = new Pair<String,String>("","");    // succeeds

  Pair<Integer,Integer> pair1 = arr[0];   // error
  Pair<?,?>             pair2 = arr[0];       // ok

  Integer i = pair2.getFirst();     // error
  Object  o = pair2.getFirst();    // ok

  pair2.setSecond(i);       // error
}

However, a Pair<?,?>[] is semantically different from the illegal Pair<Integer,Integer>[] .  It is not homogenous, but contains a mix of arbitrary pair types.  The compiler does not and cannot prevent that they contain different instantiations of the generic type.  In the example, I can insert a pair of strings into what was initially supposed to be a pair of integers. 

When we retrieve elements from the array we receive references of type Pair<?,?> .   This is demonstrated in our example: we cannot assign the Pair<?,?> taken from the array to the more specific Pair<Integer,Integer> , that we really wanted to use. 

Various operations on the Pair<?,?> are rejected as errors, because the wildcard type does not give access to all operations of the referenced object. In our example, invocation of the set -methods is rejected with error messages.

Depending on the situation, an array of a wildcard parameterized type may be a viable alternative to the illegal array of a concrete (or bounded wildcard) parameterized type.  If full access to the referenced element is needed, this approach does not work and a better solution would be use of a collection instead of an array.

LINK TO THIS Practicalities.FAQ202
REFERENCES What is a reifiable type?
How can I avoid "unchecked cast" warnings?
How can I work around the restriction that there are no arrays whose component type is a concrete parameterized type?

When would I use a wildcard parameterized type instead of a concrete parameterized type?
 
Whenever you need the supertype of all or some instantiations of a generic type.
There are two typical situations in which wildcard parameterized types are used because they act as supertype of all instantiations of a given generic type: 
  • relaxing a method signature to allow a broader range of argument or return types
  • denoting a mix of instantiations of the same generic type
Details are discussed in the FAQ entries Practicalities.FAQ301 and Practicalities.FAQ006 listed in the reference section below.
LINK TO THIS Practicalities.FAQ203
REFERENCES Which role do wildcards play in method signatures?
How do I express a mixed sequence of instantiations of a given generic type?

When would I use a wildcard parameterized type with a lower bound?
 
When a concrete parmeterized type would be too restrictive.
Consider a class hierarchy where a the topmost superclass implements an instantiation of the generic Comparable interface. 

Example: 

class Person implements Comparable<Person> {
  ...
}
class Student extends Person {
  ...
}
Note, the Student class does not and cannot implement Comparable<Student> , because it would be a subtype of two different instantiations of the same generic type then, and that is illegal (details here ). 

Consider also a method that tries to sort a sequence of subtype objects, such as a List<Student>

Example: 

class Utilities {
  public static <T extends Comparable<T>> void sort(List<T> list) {
    ...
  }
  ...
}
This sort method cannot be applied to a list of students. 

Example: 

List<Student> list = new ArrayList<Student>();
...
Utilities.sort(list);       // error


The reason for the error message is that the compiler infers the type parameter of the sort method as T:=Student and that class Student is not Comparable<Student> .  It is Comparable<Person> , but that does not meet the requirements imposed by the bound of the type parameter of method sort.  It is required that T (i.e. Student ) is Comparable<T> (i.e. Comparable<Student> ), which in fact it is not.

In order to make the sort method applicable to a list of subtypes we would have to use a wildcard with a lower bound, like in the re-engineered version of the sort method below. 

Example: 

class Utilities {
  public static <T extends Comparable <? super T > > void sort(List<T> list) {
    ...
  }
  ...
}
Now, we can sort a list of students, because students are comparable to a supertype of Student , namely Person .
LINK TO THIS Practicalities.FAQ204
REFERENCES Can a subclass implement another instantiation of a generic interface than any of its superclasses does?

How do I recover the actual type of the this object in a class hierarchy?

With a getThis() helper method that returns the this object via a reference of the exact type.
Sometimes we need to define a hierarchy of classes whose root class has a field of a super type and is supposed to refer to different subtypes in each of the subclasses that inherit the field.  Here is an example of such a situation.  It is a generic Node class. 

Example (of a class with a type mismatch - does not compile):

public abstract class Node <N extends Node<N>>  {
   private final List<N> children = new ArrayList<N>();
   private final N parent;

   protected Node(N parent) {
     this.parent = parent;
     parent.children.add(this);  // error: incompatible types
   }
   public N getParent() {
     return parent;
   }
   public List<N> getChildren() {
     return children;
   }
 }

public class SpecialNode extends Node<SpecialNode> {
   public SpecialNode(SpecialNode parent) {
     super(parent);
   }
}

The idea of this class design is: in the subclass SpecialNode the list of children will contain SpecialNode objects and in another subclass of Node the child list will contain that other subtype of Node .  Each node adds itself to the child list at construction time.  The debatable aspect in the design is the attempt to achieve this addition to the child list in the superclass constructor so that the subclass constructors can simply invoke the superclass constructor and thereby ensure the addition of this node to the child list.

The class designer overlooked that in the Node superclass the child list is of type List<N> , where N is a subtype of Node .  Note, that the list is NOT of type List<Node> .  When in the superclass constructor the this object is added to the child list the compiler detects a type mismatch and issues an error message.  This is because the this object is of type Node , but the child list is declared to contain objects of type N , which is an unknown subtype of Node .

There are at least three different ways of solving the problem.

  • Declare the child list as a List<Node> and add the this object in the superclass constructor.
  • Declare the child list as a List<N> and add the this object in the subclass constructor.
  • Declare the child list as a List<N> , recover the this object's actual type, and add the this object in the superclass constructor.
Below you find the source code for each of these solutions.


Declare the child list as a List<Node> and add the this object in the superclass constructor.

If we want to add each node to the child list in the superclass constructor then we need to declare the child list as a List<Node> , because in the superclass constructor the this object is of type Node .  The Node superclass is supposed to be used in a way that the Node reference will refer to an object of type N , but this is just a convention and not reflected in the types being used.  Type-wise the this object is just a Node - at least in the context of the superclass.

Example (problem solved using a list of supertypes):

public abstract class Node <N extends Node<N>>  {
   private final List< Node<?> > children = new ArrayList< Node<?> >();
   private final N parent;

   protected Node(N parent) {
     this.parent = parent;
     parent.children.add(this);  // fine
   }
   public N getParent() {
     return parent;
   }
   public List< Node<?> > getChildren() {
     return children;
   }
 }

public class SpecialNode extends Node<SpecialNode> {
   public SpecialNode(SpecialNode parent) {
     super(parent);
   }
}


Declare the child list as a List<N> and add the this object in the subclass constructor.

Our type mismatch problem would be solved if refrained from adding the this object in the superclass constructor, but defer its addition to the subclass constructor instead.  In the context of the subclass constructor the exact type of the this object is known and there would be no type mismatch any longer.

Example (problem solved by adding the this object in the subtype constructor):

public abstract class Node <N extends Node<N>>  {
   protected final List<N> children = new ArrayList<N>();
   private final N parent;

   protected Node(N parent) {
     this.parent = parent;
   }
   public N getParent() {
     return parent;
   }
   public List<N> getChildren() {
     return children;
   }
 }

public class SpecialNode extends Node<SpecialNode> {
   public SpecialNode(SpecialNode parent) {
     super(parent);
     parent.children.add(this); // fine
   }
}





Declare the child list as a List<N> , recover the this object's actual type, and add the this object in the superclass constructor.

The problem can alternatively be solved by means of an abstract helper method that each of the subclasses implements.  The purpose of the helper method is recovering the this object's actual type. 

Example (problem solved by recovering the this object's actual type):

public abstract class Node <N extends Node<N>>  {
   private final List<N> children = new ArrayList<N>();
   private final N parent;

   protected abstract N getThis();

   protected Node(N parent) {
     this.parent = parent;
     parent.children.add( getThis() ); // fine
   }
   public N getParent() {
     return parent;
   }
   public List<N> getChildren() {
     return children;
   }
 }

public class SpecialNode extends Node<SpecialNode> {
   public SpecialNode(SpecialNode parent) {
     super(parent);
   }
   protected SpecialNode getThis() {
       return this;
   }
}

We added an abstract helper method getThis() that returns the this object with its exact type information. Each implementation of the getThis() method in one of the Node subtypes returns an object of the specific subtype N

Usually, one would try to recover type information by means of a cast, but in this case the target type of the cast would be the unknown type N .  Following this line of logic one might have tried this unsafe solution:

Example (problem solved by recovering the this object's actual type - not recommended):

public abstract class Node <N extends Node<N>>  {
   ...
   protected Node(N parent) {
     this.parent = parent;
     parent.children.add( (N)this ); // warning: unchecked cast
   }
   ...
 }
Casts whose target type is a type parameter cannot be verified at runtime and lead to an unchecked warning.  This unsafe cast introduces the potential for unexpected ClassCastException s and is best avoided. The exact type information of the object refered to by the this reference is best recovered by means of overriding a getThis() helper method.
LINK TO THIS Practicalities.FAQ205
REFERENCES What is the "getThis" trick?

What is the "getThis" trick?

A way to recover the type of the this object in a class hierarchy.
The "getThis trick" was first published by Heinz Kabutz in Issue 123 of his Java Specialists' Newsletter in March 2006 and later appeared in the book Java Generics and Collections by Maurice Naftalin and Philp Wadler, who coined the term "getThis" trick .  It is a way to recover the type of the this object  - a recovery of type information that is sometimes needed in class hierachies with a self-referential generic supertype. 

Examples of self-referential generic types are 

  • abstract class Enum<E extends Enum<E>> in the java.lang package of the JDK, or 
  • abstract class Node <N extends Node<N>> from entry FAQ205 above, or
  • abstract class TaxPayer<P extends TaxPayer<P>> in the original example discussed by Heinz Kabutz.
Self-referential generic types are often - though not necessarily - used to express in a supertype that its subtypes depend on themselves.  For instance, all enumeration types are subtypes of class Enum. T he idea is that an enumeration type Color extends Enum<Color> , an enumeration type TimeUnit extends Enum<TimeUnit> , and so on.  Similarly in the example discussed in entry  FAQ205 : each node type extends class Node parameterized on its own type, e.g. class SpecialNode extends Node<SpecialNode> .  Heinz Kabutz's example uses the same idea:  there is a class Employee that extends TaxPayer<Employee> and a class Company that extends TaxPayer<Company> .

Let us consider an arbitrary self-referential generic type SelfReferentialType<T extends SelfReferentialType<T>> .  In its implementation it may be necessary to pass the this reference to a method that expects an argument of type T , the type parameter.  The attempt results is a compile-time error message, as illustrated below:

public abstract class SelfReferentialType<T extends SelfReferentialType<T>> {
  private SomeOtherType<T> ref;
  public  void aMethod() { ref.m( this ); } // error: incompatible types
}
public interface SomeOtherType<E> {
  void m(E arg);
}
The problem is that the this reference is of type SelfReferentialType<T> , while the method m expects an argument of type T , which is a subtype of type SelfReferentialType<T> .  Since we must not supply supertype objects where subtype objects are asked for, the compiler rightly complains.  Hence the compiler is right.

However, we as developers know that conceptually all subtypes of type SelfReferentialType are subtypes of type SelfReferentialType parameterized on their own type. As a result, the type of the this reference is the type that the type parameter T stands for.  This is illustrated below:

public class Subtype extends SelfReferentialType<Subtype> { ... }
When the inherited aMethod is invoked on a Subtype object, then the this reference refers to an object of type Subtype and a Method expects a argument of type T:=Subtype .  This perfect match is true for all subtypes.  Consequently, we wished that the compiler would accept the method invocation as is. Naturally, the compiler does not share our knowlege regarding the intended structure of the class hierarchy and there are no language means to express that each Subtype extends SelfReferentialType<Subtype> .  Hence we need a work-around - and this is what the "getThis" trick provides.

The "getThis" trick provides a way to recover the exact type of the this reference.  It involves an abstract method in the self-referential supertype that all subtypes must override. The method is typically named getThis .   The intended implementation of the method in the subtype is  getThis() { return this; } , as illustrated below:

public abstract class SelfReferentialType<T extends SelfReferentialType<T>> {
  private SomeOtherType<T> ref;
  protected abstract T getThis();
  public  void aMethod() { ref.m( getThis() ); } // fine
}
public interface SomeOtherType<E> {
  void m(E arg);
}
public class Subtype extends SelfReferentialType<Subtype> {
  protected Subtype getThis() { return this; }
}
As we discussed in entry FAQ205 , the "getThis" trick is not the only conceivable work-around.
LINK TO THIS Practicalities.FAQ206
REFERENCES How do I recover the actual type of the this object in a class hierarchy?

How do I recover the element type of a container?

By having the container carry the element type as a type token.
Suppose that you are defining a pair of related interfaces which need to be implemented in pairs:

Example (of a pair of related interfaces):

interface Contained {}

interface Container< T extends Contained> {
  void add(T element);
  List<T> elements();
}

Example (of implementations of the related interfaces):
class MyContained implements Contained {
  private final String name;
  public MyContained(String name)    {this.name = name;}
  public @Override String toString() {return name;}
}
class MyContainer implements Container<MyContained> {
  private final List<MyContained> _elements = new ArrayList<MyContained>();
  public void add(MyContained element) {_elements.add(element);}
  public List<MyContained> elements()  {return _elements;}
}
Given these interfaces you need to write generic code which works on any instance of these interfaces. 

Example (of generic code using the pair of interfaces): 

class MetaContainer {
  private Container<? extends Contained> container;
  public void setContainer(Container<? extends Contained> container) {
    this.container = container;
  }
  public void add(Contained element) {
    container.add(element);                   // error
  }
  public List<? extends Contained> elements() {return container.elements();}
}


error: add(capture#143 of ? extends Contained) in Container<capture#143 of ? extends Contained> cannot be applied to Contained)
            container.add(element); 
                     ^
The MetaContainer needs to handle an unknown parameterization of the generic Container class. For this reason it holds a reference of type Container<? extends Contained> . Problems arise when the container's add() method is invoked. Since the container's type is a wildcard parameterization of class Container the compiler does not know the container's exact type and cannot check whether the type of the element to be added is acceptable and the element can safely be added to the container.  As the compiler cannot ensure type safety, it issues an error message.  The problem is not at all surprising: wildcard parameterizations give only restricted access to the concrete parameterization they refer to (see entry GenericTypes.FAQ304 for details).

In order to solve the problem, we would have to retrieve the container's exact type and in particular its element type.  However, this is not possible statically at compile-time.  A viable work-around is adding to the Container class a method that returns a type token that represents the container's element type so that we can retrieve the element type dynamically at run-time.

Example (of container with element type):

interface Container<T extends Contained> {
  void add(T element);
  List<T> elements();
  Class<T> getElementType(); 
}

class MyContainer implements Container<MyContained> {
  private final List<MyContained> _elements = new ArrayList<MyContained>();
  public void add(MyContained element) {_elements.add(element);}
  public List<MyContained> elements()  {return _elements;}
  public Class<MyContained> getElementType() {return MyContained.class;}
}

The MetaContainer can then retrieve the element type from the container by means of the container's getElementType() method..

Example (first attempt of re-engineering the meta container):

class MetaContainer {
  private Container<? extends Contained> container;
  public void setContainer(Container<? extends Contained> container) {
    this.container = container;
  }
  public void add(Contained element) {
    container.add(container.getElementType().cast(element)); // error
  }
  public List<? extends Contained> elements() {return container.elements();}
}


error: add(capture#840 of ? extends Contained) in Container<capture#840 of ? extends Contained> cannot be applied to (Contained)
            container.add(container.getElementType().cast(element));
                     ^
Unfortunately the container is still of a type that is a wildcard parameterization and we still suffer from the restrictions that wildcard parameterizations come with: we still cannot invoke the container's add() method.  However, there is a common technique for working around this kind of restriction: using a generic helper method (see Practicalities.FAQ304 for details).

Example (successfully re-engineered meta container):

class MetaContainer {
  private Container<? extends Contained> container;
  public void setContainer(Container<? extends Contained> container) {
    this.container = container;
  }
  public void add(Contained element) {
    _add (container, element);
  }
  private static <T extends Contained> void _add( Container<T> container, Contained element){
    container.add(container.getElementType().cast(element));
  }
  public List<? extends Contained> elements() {return container.elements();}
}
This programming technique relies on the fact that the compiler performs type argument inference when a generic method is invoked (see Technicalities.FAQ401 for details). It means that the type of the container argument in the helper method _add() is not a wildcard parameterization, but a concrete parameterization for an unknown type that the compiler infers when the method is invoked.  The key point is that the container is no longer of a wildcard type and we may eventually invoke its add() method.
LINK TO THIS Practicalities.FAQ207
REFERENCES Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
How do I implement a method that takes a wildcard argument?
What is the capture of a wildcard?
What is type argument inference?

What is the "getTypeArgument" trick?

A technique for recovering the type argument from a wildcard parameterized type at run-time.
A reference of a wildcard type typically refers to a concrete parameterization of the corresponding generic type, e.g. a List<?> refers to a LinkedList<String> . Yet it is impossible to retrieve the concrete parameterization's type argument from the wildcard type. The "getTypeArgument" trick solves this problem and enables you to retrieve the type argument dynamically at run-time. The previous FAQ entry demonstrates an application of this technique (see Practicalities.FAQ207 ).

Consider a generic interface and a type that implements the interface.

Example (of generic interface and implementing class):

interface GenericType< T > {
  void method(T arg);
}
class ConcreteType implements GenericType<TypeArgument> {
  public void method(TypeArgument arg) {...}
}
Note that the interface has a method that takes the type variable as an argument.

When you later use a wildcard parameterization of the generic interface and need to invoke a method that takes the type variable as an argument, the compiler will complain.  This is because wildcard parameterizations do not give full access to all methods (see entry GenericTypes.FAQ304 for details).

Example (of using a wildcard parameterization of the generic interface): 

class GenericUsage {
  private GenericType<?> reference;
  public void method(Object arg) {
    reference.method(arg);                  // error
  }
}


error: method(capture#143 of ? extends TypeArgument) in GenericType<capture#143 of ? extends TypeArgument> cannot be applied to TypeArgument)
            reference.method(arg); 
                     ^
In order to solve the problem, you add a method to the implementation of the generic interface that return a  type token .  The type token represents the type argument of the parameterization of the generic interface that the class implements. This way you can later retrieve the type argument dynamically at run-time. 

Example (of container with element type):

interface GenericType< T > {
  void method(T arg);
  Class<T> getTypeArgument(); 
}

class ConcreteType implements GenericType<TypeArgument> {
  public void method(TypeArgument arg) {...}
  public Class<TypeArgument> getTypeArgument() {return TypeArgument.class;}
}

Using the getTypeArgument() method you can then retrieve the type argument even from a wildcard parameterization.

Example (of retrieving the type argument via the "getTypeArgument" trick):

class GenericUsage {
  private GenericType<?> reference;
  public void method(Object arg) {
    _helper (reference, arg);
  }
  private static <T> void _helper( GenericType<T> reference, Object arg){
    reference.method(reference.getTypeArgument().cast(arg));
  }
}
Note that the generic helper method _helper() is needed because otherwise the interface's method would still be invoked through a reference of a wildcard type and you would still suffer from the restrictions that wildcard parameterizations come with. Using a generic helper method is a common technique for working around this kind of restriction (see Practicalities.FAQ304 for details). 

The work-around relies on the fact that the compiler performs type argument inference when a generic method is invoked (see Technicalities.FAQ401 for details). It means that the type of the reference argument in the helper method is not a wildcard parameterization, but a concrete parameterization for an unknown type that the compiler infers when the method is invoked.  The key point is that the reference is no longer of a wildcard type and we may eventually invoke its method.

The key point of the "getTypeArgument" trick is making available the type argument as a type token (typically by providing a method such as getTypeArgument() ) so that you can retrieve the type argument at run-time even in situations where the static type information does not provide information about the type argument.

LINK TO THIS Practicalities.FAQ208
REFERENCES Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
How do I implement a method that takes a wildcard argument?
What is the capture of a wildcard? 
What is type argument inference?
How do I recover the element type of a container?

 
 

Designing Generic Methods

Why does the compiler sometimes issue an unchecked warning when I invoke a "varargs" method?
 
Because you pass in a variable argument list of reifiable types.
When you invoke a method with a variable argument list (also called varargs ) you will occasionally find that the compiler issues an unchecked warning.  Here is an example:

Example (of a varargs method and its invocation):

public  static <E> void addAll(List<E> list, E... array) {
   for (E element : array) list.add(element);
}

public static void main(String[] args) {
   addAll(new ArrayList<String>(),           // fine
          "Leonardo da Vinci",
          "Vasco de Gama"
   );
   addAll(new ArrayList<Pair<String,String>>(), // unchecked warning
          new Pair<String,String>("Leonardo","da Vinci"),
          new Pair<String,String>("Vasco","de Gama")
   );
}


warning: [unchecked] unchecked generic array creation of type Pair<String,String>[] for varargs parameter
        addAll(new ArrayList<Pair<String,String>>(),
              ^
The first invocation is fine, but the second invocation is flagged with an unchecked warning.  This warning is confusing because there is no array creation expression anywhere in the source code. In order to understand, what the compiler complains about you need to keep in mind two things:
  • Variable argument lists are translated by the compiler into an array.
  • Creation of arrays with a non-reifiable component type is not permitted.
In the example above the compiler translates the varargs parameter in the method definition into an array parameter.  Basically the method declaration is translated to the following:

Example (of varargs method after translation):

public static <E> void addAll(List<E> list, E[] array) {
  for (E element : array) list.add(element);
}
When the method is invoked, the compiler automatically takes the variable number of arguments, creates an array into which it stuffs the arguments, and passes the array to the method. The method invocations in the example above are translated to the following:

Example (of invocation of varargs method after translation):

public static void main(String[] args) {
   addAll(new ArrayList<String>(),   // fine
        new String[] {
           "Leonardo da Vinci",
           "Vasco de Gama"
        }
   );
   addAll(new ArrayList<Pair<String,String>>(), // unchecked warning
          new Pair<String,String>[] {
              new Pair<String,String>("Leonardo","da Vinci"),
              new Pair<String,String>("Vasco","de Gama")
          }
   );
}
As you can see, the compiler creates a String[] for the first invocation and a Pair<String,String>[] for the second invocation. Creating a is String[] is fine, but creating a Pair<String,String>[] is not permitted. Pair<String,String> is not a reifiable type, that is, it loses information as a result of type erasure and is at runtime represented as the raw type Pair instead of the exact type Pair<String,String> .  The loss of information leads to problems with arrays of such non-reifiable component types. The reasons are illustrated in FAQ entry ParameterizedTypes.FAQ104 ; as usual it has to do with type safety issues.

If you were trying to create such an array of type Pair<String,String>[] yourself, the compiler would reject the new -expression with an error message.  But since it is the compiler itself that creates such a forbidden array, it chooses to do so despite of the type safety issues and gives you an unchecked warning to alert you to potential safety hazards.



You might wonder why the unchecked warning is needed and what peril it tries to warn about.  The example above is perfectly type-safe, because in the method implementation the array is only read and nothing is stored in the array.  However, if a method would store something in the array it could attempt to store an alien object in the array, like putting a Pair<Long,Long> into a Pair<String,String>[] .  Neither the compiler nor the runtime system could prevent it.

Example (of corrupting the implicitly created varargs array; not recommended):

Pair<String,String>[] method(Pair<String,String>... lists) {
   Object[] objs = lists;
   objs[0] = new Pair<String,String>("x","y"); 
   objs[1] = new Pair<Long,Long>(0L,0L);      // corruption !!!
   return lists;
}
public static void main(String[] args) {
   Pair<String,String>[] result 
     = method(new Pair<String,String>("Vasco","da Gama"), // unchecked warning
              new Pair<String,String>("Leonard","da Vinci"));
   for (Pair<String,String> p : result) {
     String s = p.getFirst();                 // ClassCastException
   }
}
The implicitly created array of String pairs is accessed through a reference variable of type Object[] .  This way anything can be stored in the array; neither the compiler nor the runtime system can prevent that a Pair<Long,Long> is stored in the array of Pair<String,String> . What the compiler can do is warning you when the implicit varargs array is created.  If you ignore the warning you will get an unexpected ClassCastException later at runtime.


Here is another example that illustrates the potential danger of ignoring the warning issued regarding array construction in conjunction with variable argument lists.

Example (of a varargs method and its invocation):

public final class Test { 
        static <T> T[] method_1(T t1, T t2) {
            return method_2(t1, t2);                        // unchecked warning
        }
        static <T> T[] method_2( T... args) {
            return args;
        }
        public static void main(String... args) {
            String[] strings = method_1("bad", "karma");     // ClassCastException
        }
}


warning: [unchecked] unchecked generic array creation of type T[] for varargs parameter
            return method_2(t1, t2);
                           ^
In this example the first method calls a second method and the second method takes a variable argument list.  In order to invoke the varargs method the compiler creates an array and passes it to the method. In this example the array to be created is an array of type T[] , that is, an array whose component type is a type parameter.  Creation of such arrays is prohibited in Java and you would receive an error message if you tried to create such an array yourself; see TypeParameters.FAQ202 for details.

As in the previous example, the array's component type is non-reifiable and due to type erasure the compiler does not create a T[] , but an Object[] instead.  Here is what the compiler generates:

Example (same a above, after translation by type erasure):

public final class Test { 
        static Object[] method_1( Object t1, Object t2) {
            return method_2( new Object[] {t1, t2} );                    // unchecked warning
        }
        static Object[] method_2( Object[] args) {
            return args;
        }
        public static void main(String[] args) {
            String[] strings = (String[]) method_1("bad", "karma");       // ClassCastException
        }
}
The unchecked warning is issued to alert you to the potential risk of type safety violations and unexpected ClassCastException s.  In the example, you would observe a ClassCastException in the main() method where two strings are passed to the first method.  At runtime, the two strings are stuffed into an Object[] ; note, not a String[] .  The second method accepts the Object[] as an argument,  because after type erasure Object[] is its declared parameter type. Consequently, the second method returns an Object[] , not a String[] , which is passed along as the first method's return value. Eventually, the compiler-generated cast in the main() method fails, because the return value of the first method is an Object[] and no String[] .

Again, the problem is that calling the varargs method requires creation of a array with a non-reifiable component type.  In the first example, the array in question was a Pair<String,String>[] ; in the second example, it was a T[] .  Both are prohibited in Java because they can lead to type safety problems. 


Conclusion:  It is probably best to avoid providing objects of non-reifiable types where a variable argument list is expected.  You will always receive an unchecked warning and unless you know exactly what the invoked method does you can never be sure that the invocation is type-safe.
 

LINK TO THIS Practicalities.FAQ300
REFERENCES What does type-safety mean?
What is a reifiable type?
Can I create an array whose component type is a concrete parameterized type?
Can I create an array whose component type is a wildcard parameterized type?
Why is it allowed to create an array whose component type is an unbounded wildcard parmeterized type?
Can I create an array whose component type is a type parameter?

What is a "varargs" warning?

A warning that the compiler issues for the definition of certain methods with a variable argument list.
Certain methods with a variable arguments list (called a varargs method ) lead to unchecked warnings when they are invoked.  This can occur if the declared type of the variable argument is non-reifiable, e.g. if it is a parameterized type or a type variable.  Since Java 7 the compiler does not only give an unchecked warning when such a method is invoked, but also issues a warning for the definition of such a method.  In order to distinguish between the warning issued for the definition of a debatable varargs method and the warning issued at the call site of such a method we will refer to the warning at the definition site as a varargs warning .

Here is an example:

Example (of a varargs warning):

public  static <E> void addAll(List<E> list, E... array) {  // varargs warning
   for (E element : array) list.add(element);
}

public static void main(String[] args) {
   addAll(new ArrayList<Pair<String,String>>(),             // unchecked warning
          new Pair<String,String>("Leonardo","da Vinci"),
          new Pair<String,String>("Vasco","de Gama")
   );
}



warning: [unchecked] Possible heap pollution from parameterized vararg type E
        public  static <E> void addAll(List<E> list, E... array) {
                                                                                                                  ^
warning: [unchecked] unchecked generic array creation for varargs parameter of type Pair<String,String>[]
            addAll(new ArrayList<Pair<String,String>>(),
                  ^
The addAll() method has a variable argument list E... .  The type of the variable argument is E which is a type variable.  When the addAll()   method is invoked then the type variable E is replaced by the parameterized type Pair<String,String> in the example above, which leads to an unchecked warning.  The details regarding this unchecked warning are explained in Practicalities.FAQ300 .

In order to alert the provider of the addAll() method (rather than its caller) to the trouble the method might later cause on invocation, the compiler gives a varargs warning for the method definition.  This warning was introduced in Java 7. 

The reason for the additional warning is that the caller of a varargs method cannot do anything about the unchecked warning.  At best he can blindly suppress the unchecked warning with a @SuppressWarnings("unchecked") annotation, which is hazardous because the caller cannot know whether the unchecked warning is justified or not.  Only the method's provider can judge whether the unchecked warning can safely be ignored or whether it will lead to subsequent errors due to heap pollution (see Technicalities.FAQ050 ).  For this reason the provider of a varargs method is responsible for deciding whether the unchecked warning on invocation of the method can be ignored or not. 

With a varargs warning the compiler tries to tell the provider of a varargs method:  invocation of your method can lead to type safety issues and subsequent errors in form of unexpected ClassCastExceptions exceptions (collectively called heap pollution ). 

LINK TO THIS Practicalities.FAQ300A
REFERENCES Why does the compiler sometimes issue an unchecked warning when I invoke a "varargs" method?
What is a reifiable type?
What is heap pollution? 
When does heap pollution occur?
How can I suppress a "varargs" warning?
What is the SuppressWarnings annotation?

How can I suppress a "varargs" warning?

By using a @SafeVarargs annotation.
A varargs warning can be suppressed using the @SafeVarargs annotation.  When we use this annotation on a method with a variable argument list the compiler will not only suppress the varargs warning for the method definition, but also the unchecked warnings for the method invocations.  Here is an example, first without the annotation:
 
Example (of a varargs warning):
public  static <E> void addAll(List<E> list, E... array) {  // varargs warning
   for (E element : array) list.add(element);
}

public static void main(String[] args) {
   addAll(new ArrayList<Pair<String,String>>(),             // unchecked warning
          new Pair<String,String>("Leonardo","da Vinci"),
          new Pair<String,String>("Vasco","de Gama")
   );
}



warning: [unchecked] Possible heap pollution from parameterized vararg type E
        public  static <E> void addAll(List<E> list, E... array) {

warning: [unchecked] unchecked generic array creation for varargs parameter of type Pair<String,String>[]
            addAll(new ArrayList<Pair<String,String>>(),
                  ^

Here is the same example, this time with the annotation:

Example (of a suppressed varargs warning):

@SafeVarargs
public  static <E> void addAll(List<E> list, E... array) {  // fine
   for (E element : array) list.add(element);
}

public static void main(String[] args) {
   addAll(new ArrayList<Pair<String,String>>(),          // fine
          new Pair<String,String>("Leonardo","da Vinci"),
          new Pair<String,String>("Vasco","de Gama")
   );
}

The @SafeVarargs annotation for the addAll() method eliminates both warnings.

As usual, you must not suppress warnings unless you are absolutely sure that they can safely be ignored.  See Practicalities.FAQ300C for details on suppressing the varargs warnings.

LINK TO THIS Practicalities.FAQ300B
REFERENCES What is the SuppressWarnings annotation?
Why does the compiler sometimes issue an unchecked warning when I invoke a "varargs" method?
What is a "varargs" warning?
When should I refrain from suppressing a "varargs" warning?

When should I refrain from suppressing a "varargs" warning?

When the varargs method in question can lead to heap pollution.
Suppressing a warning is always hazardous and should only be attempted when the warning can  with certainty be considered harmless and no heap pollution will ever occur.  In all other situations you shoud refrain from suppressing any warnings.

Regarding suppression of a varargs warning: The provider of a varargs method may only suppress the warning if 

  • the varargs method does not add any elements to the array that the compiler creates for the variable argument list, or
  • if the method adds an element to the array that the compiler creates for the variable argument list, the element must be type-compatible to the array's component type.
Example (of a harmless varargs method):
 
@SafeVarargs
public static <E> void addAll(List<E> list, E... array) {
            for (E element : array) list.add(element);
}

public static void main(String... args) {
            addAll(new ArrayList<Pair<String,String>>(), 
                   new Pair<String,String>("Leonardo","da Vinci"),
                   new Pair<String,String>("Vasco","de Gama")
            );
}


The addAll() method only reads the array that the compiler created for the variable argument E... array .  No heap pollution can occur; this method is harmless; the varargs warning can be ignored and therefor safely suppressed.

Example (of an incorrect and harmful varargs method):
 

public static Pair<String,String>[] modify(Pair<String,String>... lists) {  // varargs warning
            Object[] objs = lists;
            objs[0] = new Pair<String,String>("x","y"); 
            objs[1] = new Pair<Long,Long>(0L,0L);                        // corruption !!!
            return lists;
}

public static void main(String... args) {
            Pair<String,String>[] result 
              = modify(new Pair<String,String>("Vasco","da Gama"),       // unchecked warning
                       new Pair<String,String>("Leonard","da Vinci"));
            for (Pair<String,String> p : result) {
              String s = p.getFirst();                                   // ClassCastException
            }
}



warning: [unchecked] Possible heap pollution from parameterized vararg type Pair<String,String>
        private static Pair<String,String>[] modify(Pair<String,String>... lists) {
                                                                           ^
warning: [unchecked] unchecked generic array creation for varargs parameter of type Pair<String,String>[]
              = modify(new Pair<String,String>("Vasco","da Gama"), 
                      ^
The method modify() is plain wrong and should be corrected.  It adds a Pair<Long,Long> to an array that is supposed to contain only elements of type Pair<String,String> and as a result the heap is polluted.  The compiler issues a warning for the method definition as such, but does not flag the offending assignment as an error.  The invocation of method modify() also leads to a warning.  If all these warnings are ignored, an unexpected ClassCastException can occur.

While the varargs method in the example above is blatantly wrong, the situation can be far more subtle.  Here is an example:

Example (of another incorrect and harmful varargs method):

public static <T> T[] method_1(T t1, T t2) {
   return method_2(t1, t2);                      // unchecked warning
}

public static <T> T[] method_2(T... args) {      // varargs warning
   return args;
}

public static void main(String... args) {
   String[] strings = method_2("bad", "karma");  // fine
            strings = method_1("bad", "karma");  // ClassCastException
}



warning: [unchecked] unchecked generic array creation for varargs parameter of type T[]
            return method_2(t1, t2); 
                           ^
warning: [unchecked] Possible heap pollution from parameterized vararg type T
        static <T> T[] method_2( T... args) {        // varargs warning
                                      ^
Method method_2() is a generic method and has a variable argument list of type T... , where T is the type variable. As long as the varargs method is directly called, nothing bad will happen; the compiler infers that T is String in our example and returns an array of type String[]

If the varargs method is called from another generic method such as method_1() , then the compiler will pass two arguments of type Object as arguments to method method_2() due to type erasure.  It will then infer that T is Object in our example and returns an array of type Object[] , which subsequently leads to an unexpected ClassCastException .  In this situation the question is: who is to blame?  Is the varargs method incorrect, or is it incorrectly used?  It is debatable whether it is a good idea to provide a method such as method_2() where a type variable appears in the variable argument list.  In any case, suppressing the varargs warning is not advisable because this method can lead to heap pollution as demonstrated above.

In general, it is very difficult to decide whether the varargs warning can safely be suppressed.  Whenever a non-reifiable type appears in the variable argument list, an array with a non-reifiable component type is created by the compiler.  This is always hazardous.  As soon as this array becomes accessible, heap pollution can occur.  As a consequence, you can only safely suppress a varargs warning if you can make sure that the automatically created array with a non-reifiable component type (or any copy thereof) never becomes accessible for modification.

Here is an example of another unsafe varargs method:

Example (of another incorrect and harmful varargs method):

public class SomeClass<E> { 
        private Pair<E,E>[] pairs;

        public SomeClass(Pair<E,E>... args) {  // varargs warning
            pairs = args;
        }
        public Pair<E,E>[] getPairs() { 
          List<Pair<E,E>> tmp = new ArrayList<Pair<E,E>>();
          for (Pair<E,E> p : pairs)
              tmp.add(p.clone());
          return tmp.toArray(pairs);
        }

        ... more methods ...
}

public static void main(String... args) {
   SomeClass<String> test = new SomeClass<String>(new Pair<String,String>("bad", "karma"));  // unchecked warning
   Pair<?,?>[] tmp = test.getPairs();
   tmp[0] = Pair.makePair(0L,0L); 
   String s = test.pairs[0].getFirst();     // ClassCastException
}



warning: [unchecked] Possible heap pollution from parameterized vararg type Pair<E,E>
        public SomeClass(Pair<E,E>... args) { 
                                      ^
warning: [unchecked] unchecked generic array creation for varargs parameter of type Pair<String,String>[]
            SomeClass<String> test = new SomeClass<String>(new Pair<String,String>("bad", "karma")); 
                                     ^
The varargs method in question is the constructor of class SomeClass ; it stores the automatically created array with a non-reifiable component type  Pair<E,E> in a private field.  Any modification of this array can create heap pollution. Even if the class itself does not modify the array in any of its methods, matters can go wrong.  In the example, the getPairs() method creates a deep copy of the array and passes the copy to its caller.  As soon as someone gets hold of an array with a non-reifiable component type (like the copy of the pairs field in the example), illegal elements can added to the array without any error or warning from the compiler.  The heap pollution and the resulting unexpected ClassCastException is shown in the main() method.  Only if the automatically created array were confined to the class and the class were guaranteed to use the array sensibly in all situations, then the varargs warning could safely be ignored. 

In essence, there are very few situations in which you can safely suppress a varargs warning; usually the warning is justified.

LINK TO THIS Practicalities.FAQ300C
REFERENCES What is a "varargs" warning?
How can I suppress a "varargs" warning?
What is the SuppressWarnings annotation?
What is heap pollution? 
When does heap pollution occur?

Which role do wildcards play in method signatures?

They broaden the set of argument or return types that a method accepts or returns.
Consider the problem of writing a routine that prints out all the elements in a collection. In non-generic Java it might look like this: 

Example (of non-generic print method): 

void printCollection( Collection c) { 
  Iterator i = c.iterator();
  for (k = 0; k < c.size(); k++) { 
    System.out.println(i.next());
  }
}
In generic Java the same method might be implemented like this. 

Example (of generic print method):

void printCollection( Collection<Object> c) {
  for (Object e : c) {
    System.out.println(e);
  }
}
The problem is that this new version is much less useful than the old one. Whereas the old code could be called with any kind of collection as a parameter, the new code only takes Collection<Object> , which is not a supertype of all kinds of collections. For instance, it is possible to invoke the old version supplying a List<String> as an argument, while the new version rejects the List<String> argument because it has an incompatible type. 

So what we need here is the supertype of all kinds of collections and that's exactly what the unbounded wildcard parameterized type Collection<?> is. 

Example (final version of print method): 

void printCollection( Collection<?> c) {
  for (Object e : c) { 
    System.out.println(e);
  }
}
Now, we can call the print method with any type of collection. 

Bounded wildcards are used for similar purposes. The sole difference is that the set of types that they allow is smaller (because it's restricted by the respective bound).  The key idea for use of wildcards in method signatures is to allow a broader set of argument or return types than would be possible with a concrete instantiation.

LINK TO THIS Practicalities.FAQ301
REFERENCES

Which one is better: a generic method with type parameters or a non-generic method with wildcards?
 
It depends.  There is not one-size-fits-all rule.
Often, we have two alternatives for the declaration of a method:
  • We can declare the method as a non-generic method using wildcard parameterized types as argument and return types.

  • Example:  void reverse( List <?> list) { ...  }
or
  • We can declare the method as a generic method with type parameters, that is, without using wildcards.

  • Example:  <T> void reverse( List <T> list) { ... }
Whether one alternative is better than the other depends on the semantics of the method. In some situations there is no semantic difference between the two alternatives and it is mostly a matter of taste and style which technique is preferred.  But there are also semantics that cannot expressed with wildcards as well as cases that cannot be solved without wildcards.  The subsequent  entries explore the details and provide examples.
uiLINK TO THIS Practicalities.FAQ302
REFERENCES Under which circumstances are the generic version and the wildcard version of a method equivalent?
Under which circumstances do the generic version and the wildcard version of a method mean different things?
Under which circumstances is there no transformation to the wildcard version of a method possible?

Under which circumstances are the generic version and the wildcard version of a method equivalent?
 
If there is a transformation between the generic and the wildcard version that maintains the semantics.
In many situations we can replace wildcards by type parameters and vice versa.  For example, the following two signatures are semantically equivalent:
 
    void reverse( List <?> list) { ...  }
<T> void reverse( List <T> list) { ... }


In this and the subsequent entries we aim to explore not only which of two versions is better than the other, but also how we can transform between a generic and a wildcard version of a method signature. 

The Transformation

Wildcard => Generic:  The key idea for turning a method signature with a wildcard into a generic method signature is simple:  replace each wildcard by a type variable. These type variables are basically the captures of the respective wildcards, that is, the generic method signature makes the captures visible as type parameters. For example,  we can transform the following method signature
 

<T>  void fill( List <? super T> list,  T obj) { ... }
into this signature 
<S, T extends S> void fill( List <S> list,  T obj)

by replacing the wildcard " ? super T " by an additional type parameter  S .  The type relationship, namely that the former wildcard is a supertype of  T , is expressed by saying that " T extends S ".

Generic => Wildcard: Conversely, if we prefer method signatures with fewer type parameters, then we can reduce the number of type parameters by means of wildcards: replace each type parameter that appears in a parameterized argument or return type by a wildcard.  In the previous example, we would transform the method signature
 
<S, T extends S> void fill( List <S> list,  T obj)

into the signature

<T>  void fill( List <? super T> list,  T obj) { ... }

by replacing the type variable  S by a wildcard.  The type relationship, namely that  T is a subtype of  S , is expressed by giving the wildcard a lower bound, that is, by saying " ? super T ".

The transformations sketched out above do not always work.  Especially the transformation from a generic version to a wildcard version is not always possible. Problems pop up, for instance, when the generic method signature has more than one type parameter and the type parameters have certain type relationships, such as super-subtype or same-type relationships.  In such a situation it might be impossible to translate the type relationship among the type parameters into a corresponding relationship among the wildcards.  In the example above, a semantically equivalent wildcard version could be found, because the type relationship could be expressed correctly by means of the wildcard bound.  But this is not always possible, as is demonstrated in subsequent entries.

In this entry, we discuss only situations in which a transformation exists that allows for two semantically equivalent signature and the questions is: which one is better?  For illustration let us study a couple of examples.



Case Study #1

Let us consider the following  reverse method.  It can be declared as a generic method.

Example (of a method with type parameters):
 

public static  <T> void reverse( List <T> list) {
  ListIterator <T> fwd = list.listIterator();
  ListIterator <T> rev = list.listIterator(list.size());
  for (int i = 0, mid = list.size() >> 1; i < mid; i++) {
T tmp = fwd.next();
    fwd.set(rev.previous());
    rev.set(tmp);
  }
}

Alternatively, it can be declared as a non-generic method using a wildcard argument type instead.  The transformation simply replaces the unbounded type parameter  T by the unbounded wildcard " ? ".

Example (of the same method with wildcards; does not compile):
 

public  static void reverse( List <?> list) {
  ListIterator <?> fwd = list.listIterator();
  ListIterator <?> rev = list.listIterator(list.size());
  for (int i = 0, mid = list.size() >> 1; i < mid; i++) {
Object tmp = fwd.next();
    fwd.set(rev.previous());  // error
    rev.set(tmp);  // error
  }
}

The wildcard version has the problem that it does not compile. The iterators of a  List<?> are of type  ListIterator<?> , a side effect of which is that their  next and  previous methods return an Object , while their  set method requires a more specific type, namely the "capture of ?".

We can find a workaround for this problem by using raw types, as shown below.

Example (of the same method with wildcards; not recommended):
 

public  static void reverse( List <?> list) {
  ListIterator fwd = list.listIterator();
  ListIterator rev = list.listIterator(list.size());
  for (int i = 0, mid = list.size() >> 1; i < mid; i++) {
    Object tmp = fwd.next();
    fwd.set(rev.previous());  // unchecked warning
    rev.set(tmp);  //  unchecked warning
  }
}


But even that workaround is not satisfying because the compiler gives us unchecked warnings, and rightly so.  After all we are calling the  set method on the raw type  ListIterator , without knowing which type of object the iterator refers to. 

The best implementation of the wildcard version of  reverse would use a generic helper method, as shown below.

Example (of the same method with wildcards; uses helper method):
 

private static  <T> void reverseHelper( List <T> list) {
  ListIterator<T> fwd = list.listIterator();
  ListIterator<T> rev = list.listIterator(list.size());
  for (int i = 0, mid = list.size() >> 1; i < mid; i++) {
    T tmp = fwd.next();
    fwd.set(rev.previous());
    rev.set(tmp);
  }
}
public static void reverse( List <?> list) {
  reverseHelper(list);
}


This solution compiles without warnings and works perfectly well, thanks to wildcard capture.  However, it raises the question: why not use the generic version in the first place.  The helper method is exactly the generic version of our  reverse method. The wildcard version only adds overhead and does not buy the user anything.



Case Study #2

Let us start with the wildcard version this time.  We discuss the example of a  copy method.

Example (of the a method with wildcards):
 

public static <T> void copy( List <? super T> dest,  List <? extends T> src) {
  int srcSize = src.size();
  if (srcSize > dest.size())
    throw new IndexOutOfBoundsException("Source does not fit in dest");
  ListIterator <? super T> di=dest.listIterator();
  ListIterator <? extends T> si=src.listIterator();
  for (int i = 0; i < srcSize; i++) {
    di.next();
    di.set(si.next());
  }
}

It is a method that has one type parameter  T and uses two different wildcard types as argument types.  We can transform it into a generic method without wildcards by replacing the two wildcards by two type parameters.  Here is the corresponding generic version without wildcards.

Example (of the same method without wildcards):
 

public static  <U,T extends U,L extends T> void copy( List <U> dest,  List <L> src) {
  int srcSize = src.size();
  if (srcSize > dest.size())
     throw new IndexOutOfBoundsException("Source does not fit in dest");
  ListIterator <U> di = dest.listIterator();
  ListIterator <L>  si = src.listIterator();
  for (int i = 0; i < srcSize; i++) {
    di.next();
    di.set(si.next());
  }
}

The version without wildcards uses two additional type parameters  U and  L U stands for a supertype of  T and  L stands for a subtype of  T .  Basically,  U and  L are the captures of the wildcards " ? extends T " and " ? super T " from the wildcard version of the  copy method.

Semantically the two version are equivalent. The main difference is the number of type parameters.  The version without wildcards expresses clearly that 3 unknown types are involved:  T , a supertype of  T , and a subtype of  T . In the wildcard version this is less obvious.  Which version is preferable is to the eye of the beholder.



Case Study #3

Let's study the example of a  fill method, which has been mentioned earlier, greater detail. Let's start with the generic version without wildcards and let's try to figure out whether we can get rid of the type parameters by means of wildcards.

Example (of the a method with type parameters):
 

public static  <S, T extends S> void fill( List <S> list,  T obj) {
  int size = list.size();
  ListIterator <S> itr = list.listIterator();
  for (int i = 0; i < size; i++) {
    itr.next();
    itr.set(obj);
  }
}

The method takes two type parameters  S and  T and two method parameters: an unknown instantiation of the generic type  List , namely  List<S> , and an object of unknown type  T . There is a relationship between  S and  T S is a supertype of  T

When we try to eliminate the type parameters we find that we can easily replace the type parameter  S by a wildcard, but we cannot get rid of the type parameter  T . This is because there is no way to express by means of wildcards that the  fill method takes an argument of unknown type.  We could try something like this:

Example (of the same method with wildcards; does not work):
 

public static  void fill( List <?> list,  Object obj) {
  int size = list.size();
  ListIterator <?> itr = list.listIterator();
  for (int i = 0; i < size; i++) {
    itr.next();
    itr.set(obj);  // error
  }

}

The first problem is that this version does not compile; the problem can be reduced to an unchecked warning by using a raw type  ListIterator instead of the unbounded wildcard  ListIterator<?> .  But the the real issues is that this signature gives up the relationship between the element type of the list and the type of the object used for filling the list.  A semantically equivalent version of the  fill method would look like this:

Example (of the same method with wildcards):
 

public static  <T>  void fill( List <? super T> list,  T obj) {
  int size = list.size();
    ListIterator <? super T> itr = list.listIterator();
    for (int i = 0; i < size; i++) {
      itr.next();
      itr.set(obj);
  }

}

Now, we have successfully eliminated the need for the type parameter  S , which stands for the list's element type, by using the " ? super T " wildcard, but we still need the type parameter  T .  To this regard the example is similar to the copy method discussed earlier, because we can reduce the number of type parameters by means of wildcards, but we cannot entirely eliminate the type parameters.  Which version is better is a matter of style and taste.



Conclusion:  In all these examples it is mostly a matter of taste and style whether you prefer the generic or the wildcard version.  There is usually trade-off between ease of implementation (the generic version is often easier to implement) and complexity of  signature (the wildcard version has fewer type parameters or none at all). 
LINK TO THIS Practicalities.FAQ302A
REFERENCES Should I use wildcards in the return type of a method?
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard type?
What is the capture of a wildcard?
Under which circumstances do the generic version and the wildcard version of a method mean different things?
Under which circumstances is there no transformation to the wildcard version of a method possible?

Under which circumstances do the generic version and the wildcard version of a method mean different things?
 
When a type parameter appears repeatedly in a generic method signature and in case of multi-level wildcards.
In many situations we can replace wildcards by type parameters and vice versa.  For example, the following two signatures are semantically equivalent:
 
    void reverse( List <?> list) { ...  }
<T> void reverse( List <T> list) { ... }


In the previous entry we saw several examples of equivalent method signature, but there are also situations in which the generic version and the wildcard version of a method signature mean different things. These situations include generic method signature in which a type parameter appears repeated  and method signatures in which multi-level wildcards, such as  List<Pair<?,?>> , appear.  In the following we study a couple of examples.



Case Study #1

Let us consider the implementation of a  reverse method.  It is slightly different from the  reverse method we discussed in the previous entry. The key difference is that the  List type, and with it the type parameter  T , appears twice in the method's signature: in the argument type and the return type.  Let's start again with the generic version of  the  reverse method.

Example (of a method with type parameters):
 

public static  <T> List <T> reverse( List <T> list) {
  List<T> tmp = new ArrayList<T>(list);
  for (int i = 0; i < list.size(); i++) {
    tmp.set(i, list.get(list.size() - i - 1));
  }
  return tmp;
}

If we tried to declare this method as a non-generic method using wildcards, a conceivable signature could look like this.

Example (of the same method with wildcards; does not compile):
 

public static  List <?> reverse( List <?> list) {
  List<?> tmp = new ArrayList<?>(list);  // error
  for (int i = 0; i < list.size(); i++) {
    tmp.set(i, list.get(list.size() - i - 1)); 
// error
  }
  return tmp;

}

The first problem is that this version does not compile; the problem can be reduced to an unchecked warning by using the raw types  List and  ArrayList instead of the unbounded wildcards  List<?>  and ArrayList<?> .  Even the warnings can be eliminated by relying on wildcard capture and using a generic helper method.  But one fundamental issue remains: the wildcard version has an entirely different semantic meaning compared to the generic version. 

The generic version is saying:  the  reverse method accepts a list with a certain, unknown element type and returns a list of that same type.  The wildcard version is saying:  the  reverse method accepts a list with a certain, unknown element type and returns a list of  a potentially different type.  Remember, each occurrence of a wildcard stands for a potentially different type.  In principle, the  reverse method could take a  List<Apple> and return a  List<Orange> . There is nothing in the signature or the implementation of the  reverse method that indicates that "what goes in does come out".  In other words, the wildcard signature does not reflect our intent correctly.

Conclusion:  In this example it the generic version and the wildcard version have different meaning. 



Case Study #2

Another example where more than one wildcard occurs in the signature of the method.

Example (of a method with type parameters):
 

class Pair<S,T> {
  private S first;
  private T second;
  ...
  public Pair(S s,T t) { first = s; second = t; }

  public static  <U> void flip( Pair <U,U> pair) { 
     U tmp = pair.first;
     pair.first = pair.second; 
     pair.second = tmp; 
  }

When we try to declare a wildcard version of the generic  flip method we find that there is no way of doing so.  We could try the following:

Example (of the same method with wildcards; does not compile):
 

class Pair<S,T> {
  private S first;
  private T second;
  ...
  public Pair(S s,T t) { first = s; second = t; }

  public static void flip( Pair <?,?> pair) {
    Object tmp = pair.first;
    pair.first = pair.second;  // error: imcompatible types
    pair.second = tmp;  // error: imcompatible types
  }

But this wildcard version does not compile, and rightly so.  It does not make sense to flip the two parts of a  Pair<?,?> .  Remember, each occurrance of a wildcard stands for a potentially different type.  We do not want to flip the two parts of a pair, if the part are of different types.  This additional requirement, that the parts of the pair must be of the same type, cannot be expressed by means of wildcards. 

The wildcard version above would be equivalent to the following generic version:

Example (of the generic equivalent of the wildcard version; does not compile):
 

class Pair<S,T> {
  private S first;
  private T second;
  ...
  public Pair(S s,T t) { first = s; second = t; }

  public static  <U,V> void flip( Pair <U,V> pair) {
     U tmp = pair.first;
     pair.first = pair.second;  // error: imcompatible types
     pair.second = tmp;  // error: imcompatible types
  }

Now it should be obvious that the wildcard version simply does not express our intent. 

Conclusion:  In this example only the generic version allows to express the intent correctly.



Case Study #3

If a method signature uses multi-level wildcard types then there is always a difference between the generic method signature and the wildcard version of it. Here is an example.  Assume there is a generic type  Box and we need to declare a method that takes a list of boxes.

Example (of a method with a type parameter):

public static  <T> void print1( List <Box<T>> list) {
  for (Box<T> box : list) {
    System.out.println(box);
  }
}

Example (of method with wildcards):
 
public static void print2( List <Box<?>> list) {
  for (Box<?> box : list) {
    System.out.println(box);
  }
}

Both methods are perfectly well behaved methods, but they are not equivalent.  The generic version requires a homogenous list of boxes of the same type.  The wildcard version accepts a heterogenous list of boxes of different type.  This becomes visible when the two  print methods are invoked. 

Example (calling the 2 versions):
 

List <Box<?>> list1 = new ArrayList<Box<?>>();
list1.add(new Box<String>("abc"));
list1.add(new Box<Integer>(100));

print1(list1);  // error
print2(list1);  // fine

List <Box<Object>> list2 = new ArrayList<Box<Object>>();
list2.add(new Box<Object>("abc"));
list2.add(new Box<Object>(100));

print1(list2);  // fine
print2(list2); // error


error: <T>print1( Box<T>>) cannot be applied to ( Box<?>>)
        print1(list1); 
        ^
error: print2( Box<?>>) cannot be applied to ( Box<Object>>)
        print2(list2); 
        ^

First, we create a list of boxes of different types and stuff a  Box<String> and a  Box<Integer> into the list. This heterogenous list of type  List<Box<?>> cannot be passed to the generic method, because the generic method expects a list of boxes of the same type.

Then, we create a list of boxes of the same type, namely of type  Box<Object> , and we stuff two  Box<Object> objects into the list.  This homogenous list of type  List<Box<Object>>   cannot be passed to the wildcard method, because the wildcard method expects a list of boxes, where there is no restriction regarding the type of the boxes.

Let us consider a third version of the  print method, again with wildcards, but more relaxed so that it accepts either type of list, the homogenous and the heterogenous list of boxes.

Example (of another wildcard version):
 

public static void print3( List <? extends Box<?>> list) {
  for (Box<?> box : list) {
    System.out.println(box);
  }
}

Example (calling all 3 versions):
 
List <Box<?>> list1 = new ArrayList<Box<?>>();
list1.add(new Box<String>("abc"));
list1.add(new Box<Integer>(100));

print1(list1);  // error
print2(list1);  // fine
print3(list1);  // fine

List <Box<Object>> list2 = new ArrayList<Box<Object>>();
list2.add(new Box<Object>("abc"));
list2.add(new Box<Object>(100));

print1(list2);  // fine
print2(list2);  // error
print3(list2);  // fine


No matter how we put it, the generic version and the wildcard versions are not equivalent.

Conclusion: In this example it the generic version and the wildcard version have different meaning. 

uiLINK TO THIS Practicalities.FAQ302B
REFERENCES What do multi-level wildcards mean?
If a wildcard appears repeatedly in a type argument section, does it stand for the same type?
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard type?
What is the capture of a wildcard?
Under which circumstances are the generic version and the wildcard version of a method equivalent?
Under which circumstances is there no transformation to the wildcard version of a method possible?

Under which circumstances is there no transformation to the wildcard version of a method possible?
 
I f a type parameter has more than one bound.
Wildcards can have at most one upper bound, while type parameters can have several upper bounds.  For this reason, there is not wildcard equivalent for generic method signatures with type parameter with several bounds.  Here is an example.

Example (of a method with a type parameter with more than one bound):
 

public interface State {
  boolean isIdle();
}
public static  <T extends Enum<T> & State> boolean hasIdleState( EnumSet <T> set) {
  for (T state : set) 
    if (state.isIdle()) return true;
  return false;
}
This  hasIdleState method has a type parameter that must be a enum type that implements the  State interface.  The requirement of both being an enum type and implementing an interface cannot be expressed by means of wildcards.  If we tried it it would look like this:

Example (of the same method without type parameters; does not compile):
 

public static boolean hasIdleState( EnumSet <? extends Enum<?> & State> set) {  // error
  ...
}
This attempt fails because a wildcard cannot have two bounds and for this reason the expression " ? extends Enum<?> & State " is illegal syntax. 

Conclusion: In this example there is no way to find an equivalent version with wildcards and the generic version is the only viable solution. 

uiLINK TO THIS Practicalities.FAQ302C
REFERENCES What is the difference between a wildcard bound and a type parameter bound?
Under which circumstances are the generic version and the wildcard version of a method equivalent?
Under which circumstances do the generic version and the wildcard version of a method mean different things?

Should I use wildcards in the return type of a method?


Avoid it, if you can.
Methods that return their result through a reference of a wildcard type are rarely a good idea.  The key problem is that access to the result is restricted and there is often not much the caller can do with the result he receives.  Remember, access to an object through a reference of a wildcard type is restricted; the restrictions depend on the sort of wildcard being used.  For this reason wildcard return types are best avoided.

Example (of a method with a wildcard return type; not recommended):
 

List<?> modifyList(List<?> list) { 
  ... 
  return list;
}

List<String> names = ...
List<?> result = modifyList(names);
result.add("Bobby Anderson");  // error

Since the result is returned through a wildcard reference, a whole bunch of methods cannot be invoked on the result.  A generic method would in this example be way more useful.

Example (alternative generic method; recommended):
 

<T>  List<T> modifyList(List<T> list) { 
  ... 
  return list;
}

List<String> names = ...
List<String> result = modifyList(names);
result.add("Bobby Anderson");  // fine


It is hard to imagine that a method such as  modifyList would be sensible in the first place. Most likely it is bad, if not buggy design.  After all it is weird that a method received one unknown type of list as input and returns another unknown type of list as output.  Does it turn a  List<Apples> into a  List<Oranges> ? The generic version is more likely to be the more sensible signature to begin with.  But there are examples, even in the JDK, where methods return wildcard types and the design looks reasonable at first sight, and yet suffers from the restrictions outlined above. The remainder of this FAQ entry discusses such a  more realistic example.  If you are not interested in further details, feel free to skip the rest of this entry.  It's quite instructive though, if you're interested in learning how to design generic classes properly.



A More Comprehensive Example

The Problem

As promised, we are going to study an example from the JDK to illustrate the problems with methods that return wildcard types.   The example is taken from the  JDK package  java.lang.ref .  This package provides reference classes, which support a limited degree of interaction with the garbage collector.  All these reference classes are subtypes of a  super class named  Reference<T>

Example (sketch of class  java.lang.ref.Reference ):

public abstract class 
Reference<T>
 {


 public T get() { ... }
 public void clear() { ... }
 ...



}
There are two reference classes of interest  SoftReference<T> and  WeakReference<T> . Instances of the reference classes can be registered with a reference queue. 

Example (sketch of class  java.lang.ref.WeakReference ):



public class 

WeakReference<T>
 extends Reference<T> {
 public WeakReference(T referent) { ... }
 public WeakReference(T referent, 
ReferenceQueue<? super T>
 q) { .. }
}
This reference queue is described by a type named  ReferenceQueue<T> . Its  poll and  remove methods return elements from the queue through a wildcard reference of type  Reference<? extends T>

Example (sketch of class  java.lang.ref.ReferenceQueue ):


public class 

ReferenceQueue<T>
 {

 public

 




Reference<? extends T> 
remove

() { ... }


 public

 




Reference<? extends T> 
remove

(long timeout) { ... }


 public

 





Reference<? extends T>
 
poll() { ... }
}
The methods of the  ReferenceQueue<T>  type are examples of methods that return their result through a wildcard type.  The purpose of the reference classes and the reference queue is of no relevance for our discussion.  What we intend to explore are the consequences of the wildcard return type of the reference queue's methods.

Let's consider a use case for these reference classes.  It is common that the actual reference types are subtypes of the reference classes from the JDK.  This is because a reference type often must maintain additional data.  In our example this subtype is called  DateReference and it is weak reference to a date object. It caches the representation of the referenced date as a time value and has a couple of additional methods.

Example (of a user-defined reference class):
 

public class WeakDateReference<T extends Date> extends WeakReference<T> {
    long time;

    public  WeakDateReference (T t) {
        super(t);
        time = t.getTime();
    }
    public  WeakDateReference (T t,ReferenceQueue<? super T> q) {
        super(t,q);
        time = t.getTime();
    }
    public long getCachedTime() { return time; }

    public boolean isEquivalentTo(DateReference<T> other) {
        return this.time == other.getCachedTime();
    }
    public boolean contains(T t) {
        return this.get() == t;
    }
}


Let's now create such a weak date reference and register it with a reference queue.

Example (of using a user-defined reference class with a reference queue):

ReferenceQueue<Date> queue = new ReferenceQueue<Date>();
Date date = new Date();
WeakDateReference<Date> dateRef  = new WeakDateReference<Date>(date, queue);

The reference queue will later contain weak date references that have been cleared by the garbage collector. When we retrieve entries from the reference queue,  they are passed to us through a reference of a the wildcard type  Reference<? extends Date> , because this is the way the reference queue's methods are declared.

Example (of using a user-defined reference class with a reference queue):


WeakDateReference<Date>    deadRef = queue.poll();     // error 
Reference<? extends Date> deadRef = queue.poll();     // fine

error: incompatible types
found   : Reference<capture of ? extends Date>
required: WeakDateReference<.Date>
     WeakDateReference<Date> deadRef = queue.poll(); 
                                                 ^
What is returned is a reference of type  Reference<? extends Date> pointing to an object of type  WeakDateReference<Date> .  If we now try to use the returned object we find that we cannot access the object as would like to.  In particular, some of the methods of  my weak date reference type cannot be called.

Example (of using the returned reference object):

Reference<? extends Date> deadRef = queue.poll();

long time = deadRef.getCachedTime();                                      // error
long time = (( WeakDateReference<Date> )deadRef).getCachedTime();           // unchecked warning
long time = (( WeakDateReference<? extends Date> )deadRef).getCachedTime(); // fine


error: cannot find symbol
symbol  : method getCachedTime()
location: class Reference<capture of ? extends Date>
        time = deadRef.getCachedTime(); 
                      ^
warning: [unchecked] unchecked cast
found   : Reference<capture of ? extends Date>
required: WeakDateReference<Date>
        time = ((WeakDateReference<Date>)deadRef).getCachedTime(); 
                                         ^

Before we can access any of the weak date reference type's methods we must cast down from its super-type  Reference to its own type WeakDateReference . This explains why the first invocation of the getCachedTime method fails; the super-type Reference does not have any such method.

So, we must cast down. We would like to cast the returned reference variable of type  Reference<? extends Date>  to the object's actual type  WeakDateReference<Date> , but the compiler issues an unchecked warning.  This warning is justified because the reference queue can potentially hold a mix of weak and soft references of all sorts as long as they refer to a  Date object or a subtype thereof.  We know that the reference queue only holds objects of our weak date reference type, because we know the context of our little sample program.  But the compiler can impossibly know this and rejects the cast to  WeakDateReference<Date> based on the static type information as an unchecked cast. 

We can safely cast down from the type  Reference<? extends Date>  to the wildcard type  WeakDateReference<? extends Date> though.  This is safe because the two types have the same type argument " ? extends Date ".  The compiler can ensure that type  WeakDateReference<? extends Date>  is a subtype of  Reference<? extends Date> and the JVM can check at runtime based on the raw types that the referenced object really is a  WeakDateReference

So, we invoke the weak date reference methods through a reference of the wildcard type  WeakDateReference<? extends Date> .  This fine for the  getCachedTime method, but fails when we try to invoke methods in whose argument type the type parameter  T of our type  WeakDateReference<T> appears.

Example (of using the returned reference object):
 

Reference<? extends Date> deadRef = queue.poll();

long    time = (( WeakDateReference<? extends Date> )deadRef).getCachedTime();         // fine
boolean equv = ((WeakDateReference<? extends Date>)deadRef).isEquivalentTo(dateRef); // error
boolean cont = ((WeakDateReference<? extends Date>)deadRef).contains(date);         // error


error: isEquivalentTo(WeakD ateReference<capture of ? extends Date>) 
in Wea
kDateReference<capture of ? extends Date> 
cannot be applied to (
WeakDateReference<Date>)
boolean equv  = ((WeakDateReference<? extends Date>)deadRef).isEquivalentTo(dateRef) ;
                       ^
error: contains(capture of ? extends Dat e)
in WeakDateReference<capture of ? extends Da
te>
cannot be applied to (Date)

        boolean cont = ((WeakDateReference<? extends Date>)deadRef).contains (date);
                       ^
This illustrates the problems that wildcard return types introduce: certain methods cannot be invoked through the returned wildcard reference.  In other word, there is not much you can do with the result.  How severe the restrictions are, depends on te nature of the wildcard type, the type of the returned object and the signatures of the methods that shall be invoked on the returned object.  In our example we are forced to access the result through a reference of type  WeakDateReference<? extends Date> . As a consequence, we cannot invoke the methods  boolean isEquivalentTo(DateReference<T> other) and  boolean contains(T t) , because the type parameter  T appears in their argument types. 



Conclusion

Can or should we conlcude that methods with wildcard return types are always wrong?  Not quite.  There are other examples in the JDK, where the wildcard return type does not impose any problems.  The most prominent example is the generic class  java.lang.Class<T> .  It has a number of methods that return wildcard such as 
Class<?> Class<? super T> , and  Class<? extends U> , but at the same time class  Class<T> does not have a single method in whose argument type the type parameter T would appear.  The restriction illustrated above exists in principle, but in practice it is irrelevant, because the type in question does not have any methods whose inaccessibility would hurt.

This is different for the generic  ReferenceQueue<T> type discussed above.  The super type  Reference<T> does not have any methods in whose argument type the type parameter  T would appear, pretty much like class  Class<T> .  But, it is common that subtypes of type  Reference<T> are defined and used, and there is no reason why those subtypes shouldn't be generic and have method in whose argument type the type parameter  T would appear.   And there we are ... and hit the limits.



A Conceivable Solution

The recommendation is: avoid wildcard return types if you can.  The question is: can we avoid the wildcard return type in the reference queues's methods?   The answer is: yes, but it comes at a cost.  In order to understand what the trade-off is we need to find out why the reference queue returns a wildcard type instead of a concrete parameterized type.  After all, no other queue type returns a wildcard from any of its methods; consider for instance  java.util.Queue or  java.util.concurrent.BlockingQueue

The crux in case of the  ReferenceQueue is its interaction with the  Reference type .  Class  Reference and all its subclasses have constructors that permit attachment of a reference queue to a reference object.  In class  Reference this constructor is package visible, in the subclasses it is  public .

Example (excerpt from class  java.lang.ref.Reference ):

public abstract class 
Reference<T>
 {

 ReferenceQueue<? super T> queue;
 Reference(T referent) { 

... }


 
Reference(T referent, 

ReferenceQueue<? super T>

 queue) { 



... }




 public T get() { ... }
 public void clear() { ... }
 ...



}
The package visible constructor takes the wildcard instantiation  ReferenceQueue<? super T>  as the argument type and thereby allows to attach a reference queue for references of a supertype, say  Date , to a reference for a subtype, say  NamedDate .

Example (of using a reference with a reference queue):

ReferenceQueue< Date > queue = new ReferenceQueue<Date>();
NamedDate date = new NamedDate("today");
WeakReference< NamedDate > dateRef  = new WeakReference< NamedDate >(date, queue);

Thanks to the wildcard argument type in the reference's constructor we can place references of type  Reference<NamedDate> into a reference queue of type  ReferenceQueue<Date>

Inside class  Reference , at some point in time, the reference puts itself into its attached reference queue.  For this purpose the type  ReferenceQueue has a package visible  enqueue method.

Example (excerpt from class  java.lang.ref.ReferenceQueue ):


public class 

ReferenceQueue<T>
 {

 
boolean enqueue(

Reference<? extends T>

 ref) { ... }



 public

 




Reference<? extends T> 
remove

() { ... }


 public

 




Reference<? extends T> 
remove

(long timeout) { ... }


 public

 




Reference<? extends T> 
poll() { ... }
}
This  enqueue method must accept a Reference<? extends T> as an argument, because it is permitted that a reference of a subtype can be put into the reference queue.  Like in the example above, where we registered a  Reference<NamedDate> with a  ReferenceQueue<Date> .  If the  enqueue method required an argument of the concrete type  Reference<T>  then we could never store a  Reference<NamedDate> in a  ReferenceQueue<Date> .

A consequence of accepting references of type  Reference<? extends T> in the constructor is that the exact type of the references in the queue is unknown. All retrieval methods, such as  poll and  remove , have no choice and must return the same wildcard type that was accepted in the constructor .  This is the reason why the reference queue's poll and remove methods return wildcard types instead of concrete type.

If we want to get rid of the wildcard return type we must give up the ability to attach a reference queue for references of a supertype, say  Date , to a reference for a subtype, say  NamedDate .  An alternative design would look like this:

Example (sketch of a revised  Reference class; different from JDK version ):

public abstract class 
Reference<T>
 {

 ReferenceQueue<T> queue;
 Reference(T referent) { 

... }


 Reference(T referent, 


ReferenceQueue<T>
 queue) { 

... }





 public T get() { ... }
 public void clear() { ... }
 ...



}
Example (sketch of a revised  ReferenceQueue class ; different from JDK version ):

public class 

ReferenceQueue<T>
 {

 boolean enqueue(


Reference<T>

 
ref) { ... }


 public

 






Reference<T> 
remove

() { ... }


 public

 




Reference<T> 
remove

(long timeout) { ... }


 public

 





Reference<T>




 
poll() { ... }
}
After such a redesign we can not longer place references to  NamedDate into a reference queue for reference to  Date .

Example (of using a reference with a reference queue ; different from JDK version ):
 

ReferenceQueue< Date > queue = new ReferenceQueue<Date>();
NamedDate date = new NamedDate("today");
WeakReference< NamedDate > dateRef  = new WeakReference< NamedDate >(date, queue);  // error

In return we now receive a concrete parameterized type when we take references out of the queue and the concrete type gives us full access to the reference type.  The restrictions resulting from wildcard return types are eliminated.

Example (of using a user-defined reference type ; different from JDK version ):
 

Reference <Date> deadRef = queue.poll();

long    time = (( WeakDateReference <Date> )deadRef).getCachedTime();         // fine
boolean equv = ((WeakDateReference<Date>)deadRef).isEquivalentTo(dateRef); // fine
boolean cont = ((WeakDateReference<Date>)deadRef).contains(date);          // fine


As you can see, there is a trade-off: the flexibility to put refererences to a subtype into a reference queue of references to a supertype costs us limited access to the references retrieved from the queue, and vice versa.  The design decisions made for the reference queue are certainly reasonable, because user-defined reference types with sophisticated functionality are probably rare and hence the restrictions from the wildcard return type will not hit too many programmers.

Nonetheless, the case study illustrates that design decisions made in one place have consequences in other places.  As a general rule, be aware of the restrictions that come with wildcard return types and avoid then if you can, unless you have a compelling reason to use them anyway. 

LINK TO THIS Practicalities.FAQ303
REFERENCES Under which circumstances are the generic version and the wildcard version of a method equivalent?
Under which circumstances do the generic version and the wildcard version of a method mean different things?
Under which circumstances is there no transformation to the wildcard version of a method possible?
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard type?
Which methods that use the type parameter in the argument or return type are accessible in an unbounded wildcard instantiation?
Which methods that use the type parameter in the argument or return type are accessible in an upper bound wildcard instantiation?
Which methods that use the type parameter in the argument or return type are accessible in a lower bound wildcard instantiation?
Which methods that use the type parameter as type argument of a parameterized argument or return type are accessible in a wildcard instantiation?
Which methods that use the type parameter as upper wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?
Which methods that use the type parameter as lower wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?

How do I implement a method that takes a wildcard argument?
 
Using a generic helper method and wildcard capture.
Consider the situation where you decided that a certain method should take arguments whose type is a wildcard parameterized type.  When you start implementing such a method you will find that you do not have full access to the argument.  This is because wildcards do not permit certain operations on the wildcard parameterized type. 

Example (implementation of a reverse method with wildcards; does not work): 

public static void reverse(List <?> list) {
  List<?> tmp = new ArrayList<?> (list); // error
  for (int i=0;i<list.size();i++){
    tmp. set (i,list.get(list.size()-i-1)); // error
  }
  list = tmp;
}
Using the wildcard type List<?> we can neither create a temporary copy of the argument nor can we invoke the set method.  A workaround, that works in this particular case, is use of wildcard capture and a generic helper method. 

Example (corrected implementation of a reverse method with wildcards): 

public static void reverse(List <?> list) {
  rev(list);
}
private static <T> void rev(List <T> list) {
  List<T> tmp = new ArrayList<T>(list);
  for (int i=0;i<list.size();i++){
    tmp.set(i,list.get(list.size()-i-1));
  }
  list = tmp;
}
Wildcard capture makes it possible to invoke a generic helper method.  The helper method does not use any wildcards; it is generic and has a type parameter instead.  It has unrestricted access to its arguments' methods and can provide the necessary implementation. 

Since the helper method has the exact same functionality as the original method and permits the same set of argument types, one might consider using it instead of the method with the wildcard argument in the first place. 

Example (generic version of the reverse method): 

public static <T> void reverse(List <T> list) {
  List<T> tmp = new ArrayList<T>(list);
  for (int i=0;i<list.size();i++){
    tmp.set(i,list.get(list.size()-i-1));
  }
  list = tmp;
}
LINK TO THIS Practicalities.FAQ304
REFERENCES What is the capture of a wildcard?
What is a parameterized (or generic) method?
Can I use a wildcard parameterized type like any other type?
Can I create an object whose type is a wildcard parameterized type?

How do I implement a method that takes a multi-level wildcard argument?
 
Using several  generic helper methods and wildcard capture.
Here is a an example of a method whose argument and return type is a multi-level wildcard. It is a method that takes a list whose element type is an arbitrary  pair type and return such a list.  The swapAndReverse method reverses the order all the list elements and swaps the members of each pair.  It is a contrived example for the purpose of illustrating the implementation technique. 

Example: 

class Pair<E> {
  private E fst, snd;
  public E getFirst() { return fst; }
  public void setFirst(S s) { fst = s; }
  ...
}
class Test {
  public static ArrayList<? extends Pair<?>> swapAndReverse(ArrayList <? extends Pair<?>> l) {
    ... 
  }
  public static void main(String[] args) {
        ArrayList<Pair<Integer>> list = new ArrayList<Pair<Integer>>();
        list.add(new Pair<Integer>(-1,1,0));
        list.add(new Pair<Integer>(1,0,0));
        ...
        List<?> result = swapAndReverse(list);

        ArrayList<Pair<?>> list = new ArrayList<Pair<?>>();
        list.add(new Pair<String>("a","b","c"));
        list.add(new Pair<Integer>(1,0,-1));
        list.add(new Pair<Object>(new Date(),Thread.State.NEW,5));
        ...
        List<?> result = swapAndReverse(list);
  }
}

The swapAndReverse method can be invoked on homogenous lists of pairs of the same type, such as a ArrayList<Pair<Integer>> , but also on a heterogenous list of pairs of different types, such as ArrayList<Pair<?>>

When we try to implement the method we find that the wildcard argument type does not permit invocation of the operations that we need. 

Example (implementation of a swapAndReverse method with wildcards; does not work): 

public static ArrayList<? extends Pair<?>> swapAndReverse(ArrayList <? extends Pair<?>> l) {
  ArrayList<? extends Pair<?>> list 
    = new ArrayList<? extends Pair<?>> (l); // error
  for (int i=0;i<l.size();i++){
    list. set (i,l.get(l.size()-i-1)); // error
  }
  for (Pair<?> pair : list) {
    Object e = pair.getFirst();
    pair. setFirst (pair.getSecond()); // error
    pair. setSecond (e);   // error
  }
  return list;
}
We cannot create a temporary copy of the list and cannot access the individual pairs in the list.  Hence we apply the capture-helper technique from above. 

Example (implementation of a swapAndReverse method with helper method; does not work): 

public static ArrayList<? extends Pair<?>> swapAndReverse(ArrayList <? extends Pair<?>> l) {
  return capturePairType(l);
}
private static <T extends Pair<?>> ArrayList<T> capturePairType(ArrayList <T> l) {
  ArrayList<T> list = new ArrayList<T>(l);
  for (int i=0;i<l.size();i++){
    list.set(i,l.get(l.size()-i-1));
  }
  for (T pair : list) {
    Object e = pair.getFirst();
    pair. setFirst (pair.getSecond()); // error
    pair. setSecond (e);   // error
  }
  return list;
}
The compiler will capture the type of the pairs contained in the list, but we still do not know what type of members the pairs have. We can use the capture-helper technique again to capture the pairs' type argument. 

Example (corrected implementation of a swapAndReverse method with wildcards):

public static ArrayList<? extends Pair<?>> swapAndReverse(ArrayList <? extends Pair<?>> l) {
  return capturePairType(l);
}
private static <T extends Pair<?>> ArrayList<T> capturePairType(ArrayList <T> l) {
  ArrayList<T> list = new ArrayList<T>(l);
  for (int i=0;i<l.size();i++){
    list.set(i,l.get(l.size()-i-1));
  }
  for (T pair : list) {
    captureMemberType(pair);
  }
  return list;
}
private static <E> void captureMemberType(Pair <E> pair) {
  E e = pair.getFirst();
  pair.setFirst(pair.getSecond());
  pair.setSecond(e);
}
In this case there is no alternative to the stepwise application of the capture-helper technique.  A generic version of the swapAndReverse method would have slightly different semantics.

Example (parameterized version of the swapAndReverse method): 

public static  < E ,T extends Pair <E> > ArrayList<T> swapAndReverse(ArrayList <T> l) {
  ArrayList<T> list = new ArrayList<T>(l);
  for (int i=0;i<l.size();i++){
    list.set(i,l.get(l.size()-i-1));
  }
  for (T pair : list) {
    E e = pair.getFirst();
    pair.setFirst(pair.getSecond());
    pair.setSecond(e);
  }
  return list;
}
This version of the swapAndReverse method has one disadvantage:  it does not accept a mixed list of pairs of arbitrary types, such as ArrayList<Pair<?>>

Example: 

class Test {
  public static void main(String[] args) {
        ArrayList<Pair<Integer>> list = new ArrayList<Pair<Integer>>();
        list.add(new Pair<Integer>(-1,1,0));
        list.add(new Pair<Integer>(1,0,0));
        ...
        List<?> result = swapAndReverse(list);

        ArrayList<Pair<?>> list = new ArrayList<Pair<?>>();
        list.add(new Pair<String>("a","b","c"));
        list.add(new Pair<Integer>(1,0,0));
        list.add(new Pair<Object>(new Date(),Thread.State.NEW,5));
        ...
        List<?> result = swapAndReverse(list);  // error
  }
}



error: <E,T>swapAndReverse(java.util.ArrayList<T>) in Test cannot be applied to (java.util.ArrayList<Pair<?>>)
      List<?> result = swapAndReverse(list);
                       ^
On the other hand, the generic swapAndReverse method has the advantage that it returns a concrete instantiation of ArrayList , that does not suffer from the limitations that come with the wildcard instantiation that is returned from the wildcard version of the swapAndReverse method. 
LINK TO THIS Practicalities.FAQ305
REFERENCES How do I implement a method that takes a wildcard argument?
What do multi-level wildcards mean?
What is the capture of a wildcard?
What is a parameterized or generic method?
What is a bounded type parameter?
Which types are permitted as type parameter  bounds?
Can I use a type parameter as part of its own bounds or in the declaration of other type parameters?
Can I use a wildcard parameterized type like any other type?
Can I create an object whose type is a wildcard parameterized type?

I want to pass a U and a X<U> to a method.  How do I correctly declare that method?
 
Using an upper bound wildcard parameterized type instead of a concrete parameterized type as the argument type.
Example (has a bug): 
interface Acceptor<V> {
  void accept( Task<V> task, V v);
}
interface Task<U> {
  void go(Acceptor<? super U> acceptor);
}
class AcceptingTask<U> implements Task<U> {
  public void go(Acceptor<? super U> acceptor) {
    U result = null; 
    ... produce result ... 
    acceptor.accept(this, result);  // error
  }
}


error: accept(Task<capture of ? super U>,capture of ? super U) 
in Acceptor<capture of ? super U> cannot be applied to (AcceptingTask<U>,U)
          acceptor.accept(this, result);
                  ^
This is the example of a callback interface Acceptor and its accept method which takes  result-producing task and the result. Note that the accept method takes a result of type V and a corresponding task of type Task<V>

The task is described by an interface Task .  It has a method go that is supposed to produce a result and takes an Acceptor , to which it passes the result. 

The class AcceptingTask is an implementation of the Task interface and in its implementation of the go method we see an invocation of the accept method.  This invocation fails. 

The problem with this invocation is that the accept method is invoked on a wildcard instantiation of the Acceptor , namely Acceptor<? super U> .  Access to methods through wildcard parameterized types is restricted.  The error message clearly indicates the problem.  Method accept in  Acceptor<? super U> expects a Task<capture of ? super U> and a capture of ? super U . What we pass as arguments are a AcceptingTask<U> and a U .  The argument of type U is fine because the declared argument type is an unknown supertype of U .  But the argument of type AcceptingTask<U> is a problem. The declared argument type is an instantiation of Task for an unknown supertype of U . The compiler does not know which supertype and therefor rejects all argument types. 

The crux is that the signature of the accept method is too restrictive. If we would permit instantiations of Task for subtypes of U , then it would work. 

Example (corrected): 

interface Acceptor<V> {
  void accept( Task< ? extends V> task, V v);
}
interface Task<U> {
  void go(Acceptor<? super U> acceptor);
}
class AcceptingTask<U> implements Task<U> {
  public void go(Acceptor<? super U> acceptor) {
    U result = null; 
    ... produce result ... 
    acceptor.accept(this, result);  // fine
  }
}
With this relaxed signature the accept method  in  Acceptor<? super U> expects a Task<? extends capture of ? super U> , that is, an instantiation of Task for a subtype of a supertype of U and Task<U> meets this requirement. 

The common misunderstanding here is that the signature accept(Task<V> task, V v) looks that I can pass a Task<U> whenever I can pass a U .  This is true for concrete instantiations of the enclosing type, but not when wildcard instantiations are used.  The accessibility rules for methods that take the type parameter such as V as an argument and methods that take a parameterized type instantiated on the type parameter such as Task<V> are very different. 

The solution to the problem is relaxing the signature by using a wildcard parameterized type as an argument type instead of a concrete parameterized type.

LINK TO THIS Practicalities.FAQ306
REFERENCES Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
Which methods that use the type parameter in the argument or return type are accessible in an unbounded wildcard parameterized type?
Which methods that use the type parameter in the argument or return type are accessible in an upper bound wildcard parmeterized type?
Which methods that use the type parameter in the argument or return type are accessible in a lower bound wildcard parameterized type?
Which methods that use the type parameter as type argument of a parameterized argument or return type are accessible in a wildcard parameteriezed type?
Which methods that use the type parameter as upper wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?
Which methods that use the type parameter as lower wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?
In a wildcard instantiation, can I read and write fields whose type is the type parameter? 

 
 

Working With Generic Interfaces

Can a class implement different instantiations of the same generic interface?
 
No, a type must not directly or indirectly derive from two different instantiations of the same generic interface.
The reason for this restriction is the translation by type erasure. After type erasure the different instantiations of the same generic interface collapse to the same raw type.  At runtime there is no distinction between the different instantiations any longer. 

Example (of illegal subtyping from two instantiations of the same generic interface): 

class X implements Comparable<X> , Comparable<String> // error
  public int compareTo(X arg)     { ... }
  public int compareTo(String arg) { ... }
}
During type erasure the compiler would not only remove the type arguments of the two instantiations of Comparable , it would also try to create the necessary bridge methods. Bridge methods are synthetic methods generated by the compiler; they are needed when a class has a parameterized supertype. 

Example (same as above, after a conceivable translation by type erasure): 

class X implements Comparable , Comparable
  public int compareTo(X arg)      { ... }
  public int compareTo(String arg) { ... }
  public int compareTo(Object arg) { return compareTo((X)arg); }
  public int compareTo(Object arg) { return compareTo((String)arg); }
The bridge method generation mechanism cannot handle this.
LINK TO THIS Practicalities.FAQ401
REFERENCES What is type erasure?
What is a bridge method?
Can I use different instantiations of a same generic type as bounds of a type parameter?
Can a subclass implement another instantiation of a generic interface than any of its superclasses does?
What happens if a class implements two parameterized interfaces that define the same method?

Can a subclass implement a different instantiation of a generic interface than any of its superclasses does?
 
No, the superclass determines which instantiation of a generic interface the entire class hierarchy must implement.
Example: 
class Person implements Comparable<Person> {
  public int compareTo(Person arg) { ... }
}
class Student extends Person implements Comparable<Student> {  // error
  public int compareTo(Student arg) { ... }
}


error: java.lang.Comparable cannot be inherited with different arguments: <Student> and <Person>
    class Student extends Person implements Comparable<Student> {
    ^
The Student subclass would be implementing two different instantiations of the generic Comparable interface, which is illegal.  The consequence is that a superclass that implement a certain instantiation of a generic interface determines for all its subclasses which instantiation of the interface they must implement.  No subclass can ever implement another instantiation of the generic interface. 
 


This consequence makes proper use of generic interfaces fairly challenging.  Here is another example of the effect, using the Delayed interface from the java.util.concurrent package. 

Example (interface java.util.concurrcent.Delayed ): 

public interface Delayed extends Comparable<Delayed> {
    long getDelay(TimeUnit unit);
}
The Delayed interface is a sub-interface of an instantiation of the Comparable interface and thereby takes away the chance that any implementing class can ever be comparable to anything else but a Delayed object. 

Example: 

class SomeClass implements Delayed, Comparable<SomeClass> {  // error 
  public long getDelay(TimeUnit unit)   { ... }
  public int compareTo(Delayed other)   { ... }
  public int compareTo(SomeClass other) { ... }
}

error: java.lang.Comparable cannot be inherited with different arguments: <java.util.concurrent.Delayed> and <SomeClass>
    class SomeClass implements Delayed, Comparable<SomeClass> {
    ^
LINK TO THIS Practicalities.FAQ402
REFERENCES Can a class implement different instantiations of the same generic interface?

What happens if a class implements two parameterized interfaces that both define a method with the same name?
 
If the two method have the same erasure then the class is illegal and rejected with a compile-time error message.
If, after type erasure, two inherited methods happen to have the same erasure, then the compiler issues an error message. 

Example (of illegal class definition; before type erasure): 

interface Equivalent <T> {
  boolean equalTo(T other);
}
interface EqualityComparable <T> {
  boolean equalTo(T other);
}
class SomeClass implements Equivalent <Double>, EqualityComparable <SomeClass> // error
  public boolean equalTo(Double other) { ... }
  public boolean equalTo(SomeClass other) { ... }
}


error: name clash: equalTo(T) in EqualityComparable<SomeClass> and equalTo(T) in Equivalent<java.lang.String> have the same erasure, yet neither overrides the other
    class SomeClass implements EqualityComparable<SomeClass>, Equivalent<Double> {
    ^
During type erasure the compiler does not only create the type erased versions of the two colliding interfaces, it would also try to create the necessary bridge methods.  Bridge methods are synthetic methods generated by the compiler when a class has a parameterized supertype. 

Example (after a conceivable translation by type erasure): 

interface Equivalent {
  boolean equalTo( Object other);
}
int erface EqualityComparable {
  boolean equalTo( Object other);
}
class SomeClass implements Equivalent, EqualityComparable {
  public boolean equalTo(Double other)    { ... }
  public boolean equalTo(Object other)    { return equalTo((Double)other); }
  public boolean equalTo(SomeClass other) { ... }
  public boolean equalTo(Object other)    { return equalTo((SomeClass)other); }
}
The bridge methods would have the same signature. Instead of resolving the conflict the compiler reports an error. 

By the way, the problem is not that the class has several overloaded versions of the equalTo method.  The problem stems from the fact that the interfaces are generic and the methods have the same type erasure.  No problem occurs when the two interfaces have no type parameter. 

Example (of legal class definition): 

interface Equivalent {
  boolean equalTo( Double other);
}
interf ace EqualityComparable {
  boolean equalTo( SomeClass other);
}
class SomeClass implements Equivalent, EqualityComparable {
  public boolean equalTo(Double other) { ... }
  public boolean equalTo(SomeClass other) { ... }
}
In the example above the compiler need not generate any bridge methods because the interfaces are not generic.

Note, that there is no problem if the two interfaces are generic and the conflicting methods have different type erasures

Example (of legal class definition): 

interface Equivalent <T extends Number> {
  boolean equalTo(T other);
}
interface EqualityComparable <T> {
  boolean equalTo(T other);
}
class SomeClass implements Equivalent <Double>, EqualityComparable <SomeClass> {
  public boolean equalTo(Double other) { ... }
  public boolean equalTo(SomeClass other) { ... }
}
Example (after a conceivable translation by type erasure): 
interface Equivalent {
  boolean equalTo( Number other);
}
int erface EqualityComparable {
  boolean equalTo( Object other);
}
class SomeClass implements Equivalent, EqualityComparable {
  public boolean equalTo(Double other)    { ... }
  public boolean equalTo(Number other)    { return equalTo((Double)other); }
  public boolean equalTo(SomeClass other) { ... }
  public boolean equalTo(Object other)    { return equalTo((SomeClass)other); }
}
The two equalTo methods have different erasures and then the bridge method generation mechanism create two bridge methods with different signatures and no problem occurs. 

Effects similar to ones illustrated above can be observed with a parameterized superclass and a parameterized interface if they have a method with the same type erasure. 

Last but not least, a legal way of implementing two interfaces with methods that have the same type erasure: as long as the colliding methods are instantiated for the same type argument there is no problem at all. 

Example (of legal class definition): 

class SomeClass implements Equivalent <SomeClass>, EqualityComparable <SomeClass> {
  public boolean equalTo(SomeClass other) { ... }
}
The class provide exactly one method, namely the matching one from both interfaces and the compiler generates one synthetic bridge method.  No problem.

Example (after type erasure): 

class SomeClass implements Equivalent , EqualityComparable {
  public boolean equalTo(SomeClass other) { ... }
  public boolean equalTo(Object other)    { return equalTo((SomeClass)other); }
}
LINK TO THIS Practicalities.FAQ403
REFERENCES What is type erasure?
What is a bridge method?

Can an interface type nested into a generic type use the enclosing type's type parameters?

No, but as workaround you can generify the nested interface itself. 
Nested interfaces are implicitly static. This is sometimes overlooked because the interface looks like it were a non-static member of its enclosing class, while in fact it is static. Since type parameters must not be used in any static context of a generic type, a nested interface cannot use its enclosing type's type parameters. 

Example (of a nested interface):

interface Action { 
  void run();

final class SomeAction implements Action {
  public void run() { &hellip; }
}
final class Controller <A extends Action> {
  public interface Command {
    void doIt( A action);           // error
    void undoIt( A action);         // error
  } 
  &hellip;
}

error: non-static class A cannot be referenced from a static context
   void doIt(A action);
             ^
error: non-static class A cannot be referenced from a static context
   void undoIt(A action);
               ^
The Command interface is nested into the generic Controller class.  Inside the nested interface we cannot refer to the  type parameter A of the enclosing class, because the nested interface is implicitly static and type parameters must not appear in any static context. 

So, how do we express that the Command interface mandates do/undo methods for different types of actions?  The solution is to generify the interface itself independently of the generic enclosing class. 

Example (same as above, but corrected): 

interface Action { 
  void run();

final class SomeAction implements Action {
  public void run() { &hellip; }
}
final class Controller <A extends Action> {
  public interface Command <B extends Action>  
    void doIt(B action); 
    void undoIt(B action); 
  }
  &hellip; 
}
LINK TO THIS Practicalities.FAQ404
REFERENCES Why can't I use a type parameter in any static context of the generic class?
How do I refer to an interface type nested into a generic type?

Implementing Infrastructure Methods

How do I best implement the equals method of a generic type?

Override Object.equals(Object) as usual and perform the type check using the unbounded wildcard instantiation.
The recommended implementation of the equals method of a generic type looks like the one shown in the example below.  Conceivable alternatives are discussed and evaluated later. 

Example (recommended implementation of equals ): 

class Triple<T> {
  private T fst, snd, trd;
  public Triple(T t1, T t2, T t3) {fst = t1; snd = t2; trd = t3;}
  ...
  public boolean equals( Object other) {
    if (this == other) return true;
    if (other == null) return false; 
    if (this.getClass() != other.getClass()) return false;
    Triple<?> otherTriple = (Triple<?>) other;
    return (this.fst.equals(otherTri ple.fst) 
         && this.snd.equals(otherTriple.snd)
         && this.trd.equals(otherTriple.trd));
  }
}
Perhaps the greatest difficulty is the downcast to the triple type, after the check for type match has been passed successfully.  The most natural approach would be a cast to Triple<T> , because only objects of the same type are comparable to each other. 

Example (not recommended): 

class Triple<T> {
  private T fst, snd, trd;
  public Triple(T t1, T t2, T t3) {fst = t1; snd = t2; trd = t3;}
  ...
  public boolean equals (Object other) {
    if (this == other) return true;
    if (other == null) return false; 
    if (this.getClass() != other.getClass()) return false;
    Triple<T> otherTriple = (Triple<T>) other; // unchecked warning
    return (this.fst.equals(otherTri ple.fst) 
         && this.snd.equals(otherTriple.snd)
         && this.trd.equals(otherTriple.trd));
  }
}
The cast to Triple<T> results in an "unchecked cast" warning, because the target type of the cast is a parameterized type.  Only the cast to Triple<?> is accepted without a warning. Let us try out a cast to Triple<?> instead of Triple<T>

Example (better, but does not compile): 

class Triple<T> {
  private T fst, snd, trd;
  public Triple(T t1, T t2, T t3) {fst = t1; snd = t2; trd = t3;}
  ...
  public boolean equals (Object other) {
    if (this == other) return true;
    if (other == null) return false; 
    if (this.getClass() != other.getClass()) return false;
    Triple<T> otherTriple = (Triple<?>) other; // error
    return (this.fst.equals(otherTri ple.fst)
         && this.snd.equals(otherTriple.snd)
         && this.trd.equals(otherTriple.trd));
  }
}


error: incompatible types
found   : Triple<capture of ?>
required: Triple<T>
            Triple<T> otherTriple = (Triple<?>)other;
                                    ^
This implementation avoids the"unchecked" cast, but does not compile because the compiler refuses to assign a Triple<?> to a Triple<T> .  This is because the compiler cannot ensure that the unbounded wildcard parameterized type Triple<?> matches the concrete parameterized type Triple<T> .  To make it compile we have to change the type of the local variable otherTriple from Triple<T>  to Triple<?> . This change leads us to the first implementation shown in this FAQ entry, which is the recommended way of implementing the equals method of a generic type. 
 

Evaluation of the alternative implementations.

How do the two alternative implementations, the recommended one casting to Triple<?> and the not recommended one casting to Triple<T> , compare?  The recommended implementation compiles without warnings, which is clearly preferable when we strive for warning-free compilation of our programs.  Otherwise there is no difference in functionality or behavior, despite of the different cast expressions in the source code.  At runtime both casts boils down to a cast to the raw type Triple

If there is no difference in functionality and behavior and one of the implementations raises a warning, isn't there a type-safety problem? After all, "unchecked" warnings are issued to alert the programmer to potentially unsafe code.  It turns out that in this particular cases all is fine.  Let us see why. 

With both implementations of equals it might happen that triples of different member types, like a Triple<String> and a Triple<Number> ,  pass the check for type match via getClass() and the cast to Triple<?> (or Triple<T> ). We would then compare  members of different type with each other. For instance, if a Triple<String> and a Triple<Number> are compared, they would pass the type check, because they are both triples and we would eventually compare the Number members with the String members.  Fortunately, the comparison of a String and a Number always yields false , because both String.equals and Number.equals   return false in case of comparison with an object of an imcompatible type. 

In general, every implementation of an equals method is responsible for performing a check for type match and to return false in case of mismach.  This rule is still valid, even in the presence of Java generics, because the signature of equals is still the same as in pre-generic Java: the equals method takes an Object as an argument. Hence, the argument can be of any reference type and the implementation of equals must check whether the argument is of an acceptable type so that the actual comparison for equality makes sense and can be performed. 
 

Yet another alternative.

It might seem natural to provide an equals method that has a more specific signature, such as a version of equals in class Triple that takes a Triple<T> as an argument. This way we would not need a type check in the first place.  The crux is that a version of equals that takes a Triple<T> as an argument would not be an overriding version of Object.equals(Object) , because the equals method in Object is not generic and the compiler would not generate the necessary bridge methods.  We would have to provide the bridge method ourselves, which again would result in an "unchecked" warning. 

Example (not recommended): 

class Triple<T> {
  private T fst, snd, trd;
  public Triple(T t1, T t2, T t3) {fst = t1; snd = t2; trd = t3;}
  ...
  public boolean equals ( Triple<T> other) {
    if (this == other) return true;
    if (other == null) return false; 
    return (this.fst.equals(other .fst) 
         && this.snd.equals(other.snd)
         && this.trd.equals(other.trd));
  }
  public boolean equals(Object other) {
    return equals((Triple<?>) other);      // unchecked warning
  }
}
This implementation has the flaw of raising an "unchecked" warning and offers no advantage of the recommended implementation to make up for this flaw.
LINK TO THIS Practicalities.FAQ501
REFERENCES What is a bridge method?
What is an "unchecked" warning?
What is the capture of a wildcard?
What is a wildcard capture assignment-compatible to?

How do I best implement the clone method of a generic type?


Override Object.clone() as usual and ignore the inevitable unchecked warnings.
The recommended implementation of the clone method of a generic type looks like the one shown in the example below. 

Example (implementation of clone ): 

class Triple<T> implements Cloneable {
  private T fst, snd, trd;
  public Triple(T t1, T t2, T t3) {fst = t1; snd = t2; trd = t3;}
  ...
  public Triple<T> clone() {
     Triple<T> clon = null;
     try { 
       clon = (Triple<T>) super.clone(); // unchecked warning
     } catch (CloneNotSupportedException e) { 
       throw new InternalError(); 
     }
     try { 
       Class<?> clzz = this.fst.getClass();
       Method   meth = clzz.getMethod("clone", new Class[0]);
       Object   dupl = meth.invoke(this.fst, new Object[0]);
       clon.fst = (T) dupl; // unchecked warning
     } catch (Exception e) {
       ...
     }
     try {
       Class<?> clzz = this.snd.getClass();
       Method   meth = clzz.getMethod("clone", new Class[0]);
       Object   dupl = meth.invoke(this.snd, new Object[0]);
       clon.snd = (T) dupl; // unchecked warning
     } catch (Exception e) {
       ...
     }
     try {
       Class<?> clzz = this.trd.getClass();
       Method   meth = clzz.getMethod("clone", new Class[0]);
       Object   dupl = meth.invoke(this.trd, new Object[0]);
       clon.trd = (T) dupl; // unchecked warning
     } catch (Exception e) {
       ...
     }
     return clon;
  }
}
Return type.

In our implementation we declared the return type of the clone method not as type Object , but of the more specific generic type.  This is possible, since the overriding rules have been relaxed and an overriding method in a subclass need no longer have the exact same signature as the superclass's method that it overrides.  Since Java 5.0 it is permitted that the subclass version of a method returns a type that is a subtype of the return type of the superclass's method. In our example, the method clone in class Triple<T> returns a Triple<T> and overrides the clone method in class Object , which returns an Object

The more specific return type is largely a matter of taste.  One might equally well stick to the traditional technique of declaring the return type of all clone methods as type Object .  The more specific return type is beneficial for the users of our triple class, because it saves them a cast from Object down to Triple<T> after a call to Triple<T>.clone

"unchecked cast" warnings.

The most annoying aspect of implementing clone for a generic type are the inevitable "unchecked" warnings. The warning stem from two categories of casts that are needed. 

  • Casting the result of super.clone to the generic type.
  • Casting the result of cloning any fields to the type that the type parameter stands for.
Casting the result of super.clone to the generic type.

Part of every implementation of clone is the invocation of the superclass's clone method.  The result of super.clone is either of the supertype itself or of type Object . In our example super.clone is Object.clone , whose return type is Object .  In order to access the fields of the clone returned from super.clone a cast to own type is needed. In our example this is a cast to the type Triple<T> . The target type of this cast is the generic type itself and the compiler issues the usual "unchecked cast" warning. 

In some cases the cast is not needed at all, namely when the clone produced by super.clone is already deep enough so that the fields of the clone need not be accessed.  This would be the case if all fields are either of primitive type or of an immutable reference type. 

In all other cases, there is no way to avoid the unchecked warning. A cast to Triple<?> instead of Triple<T> would eliminate the unchecked warning, but does not give the required access to the fields. The two fields in our example would be of type "capture of ?" to which we cannot assign the result of  cloning the individual fields. Alternatively we might consider a cast to the raw type Triple instead of Triple<T> , but that would give us "unchecked assignment" warnings instead of "unchecked cast" warnings.  The compiler would issue the warnings when we access the fields of our raw triple class.  No matter how we put it, we cannot avoid the unchecked warnings the cast after super.clone .  The warnings are harmless and hence best suppressed by means of the standard annotation @annotation.SuppressWarnings

Cloning the individual fields.

We must invoke the fields' clone method via reflection because we do not know whether the respective field has an accessible clone method.  Two factor play a role: 

  • Every class inherits a clone method from class Object , but Object.clone is a protected method and for this reason not part of the public interface of a class. In essence, all classes have a clone method, but only a private one, unless they explicitly provide a public clone method. 
  • Most classes that have a clone method also implement the Cloneable interface.  The Cloneable interface is an empty marker interface and does not mandate that a Cloneable class must have a public clone method.  Even if we could sucessfully cast down to Cloneable we would not have access to a clone method.  Hence, for purposes of invoking a clone method the Cloneable interface is totally irrelevant.
In the example we use reflection to find out whether the field has a public clone method. If it has a clone method, we invoke it. 

Casting the result of cloning any fields to the type that the type parameter stands for.

If individual fields must be cloned, the clone method of the respective fields' type must be invoked.  The result of this invocation of the clone method is often type Object , so that another cast is necessary.  If the field in question has the type that the enclosing class's type parameter stands for then the target of this cast is the type variable and the compiler issues the usual "unchecked cast" warning.  In our example we must clone the two fields of the unknown type T , which requires that we invoke the field's clone method via reflection.  The result of the reflective call is of type Object and we must cast from Object to the type parameter T .  Again, there is no way to avoid the unchecked casts after cloning the fields and  the warnings are best suppressed by means of the standard annotation @annotation.SuppressWarnings

More "unchecked" warnings.

If a class has fields that are of a parameterized type and these fields must be cloned then a cast from Object to the parameterized type might be necessary and the compiler issues the usual "unchecked cast" warning. 

Example: 

class Store {
  private ArrayList<String> store = new ArrayList<String>();
  ...
  public Store clone() {
    Store clon = (Store)super.clone();
    clon.store = (ArrayList<String>) this.store.clone(); // unchecked warning
  }
}
Again there is no chance to avoid the "unchecked cast" warnings and they are best suppressed by means of the standard annotation @annotation.SuppressWarnings

The reason for the undesired unchecked warnings in conjunction with the clone method stem from the fact that the clone method is a non-generic legacy method.  In situations where generic and non-generic code is mixed, unchecked warnings cannot  be avoided. 

Exception Handling.

In the example, we left open how the exceptions from reflective invocation of the members' clone methods should be handled.  Should we suppress the exceptions, or should we map them to a CloneNotSupportedException , or perhaps simply propagate the exceptions to the caller? 

Example (excerpt from implementation of clone ): 

public Triple<T> clone( ) {
     ...
     try { 
       Class<?> clzz = this.fst.getClass();
       Method   meth = clzz. getMethod ( "clone" , new Class[0]);
       Object   dupl = meth. invoke (this.fst, new Object[0]);
       clon.fst = (T)dupl; 
     } catch (Exception e) {
      ...  ???  what should be done here ??? ...
     }
     ...
}
Usually, a clone method does not throw any exceptions; at least is does not through a CloneNotSupportedException .  The point in implementing a clone method is to support cloning.  Why should a clone method throw a CloneNotSupportedException then?  It is equally unusual that a clone method would throw any other exception, because a class knows its fields and their types well enough to successfully produce a clone of each field. 

For a generic class the situation is more complex.  We do not know anything about those fields of the class whose type is a type parameter.  In particular, we do not know whether those fields are Cloneable and/or have a clone method, as was explained above.  The attempted invocation of the members' clone method via reflection bears the risk of failure, indicated by a number of exceptions raised by Class.getMethod and Method.invoke such as NoSuchMethodException , IllegalArgumentException , etc.  In this situation the clone method might in fact fail to produce a clone and it might make sense to indicate this failure by mapping all (or some) exceptions to a CloneNotSupportedException

Example (throwing a CloneNotSupportedException ): 

public Triple<T> clone( ) throws CloneNotSupportedException {
     ...
     try {
       Class<?> clzz = this.fst.getClass();
       Method   meth = clzz. getMethod ( "clone" , new Class[0]);
       Object   dupl = meth. invoke (this.fst, new Object[0]);
       clon.fst = (T)dupl; 
     } catch (Exception e) {
      throw new CloneNotSupportedException (e.toString());
     }
     ...
}
On the other hand, one might argue that a type that does not have a clone method probably needs no cloning because objects of the type can safely be referenced from many other objects at the same time.  Class String is an example.  Class String is neither Cloneable nor has it a clone method.  Class String does not support the cloning feature, because String objects are immutable, that is, they cannot be modified.  An immutable object is never copied, but simply shared among all objects that hold a reference to it.  With our exception handling above the clone method of a Triple<String> would throw a CloneNotSupportedException , which is not quite appropriate.  It would be preferable to let the original triple and its clone hold references to the shared string members. 

Example (suppressing the NoSuchMethodException ): 

public Triple<T> clone( ) {
     ...
     try { 
       Class<?> clzz = this.fst.getClass();
      Method   meth = clzz. getMethod ( "clone" , new Class[0]);
       Object   dupl = meth. invoke (this.fst, new Object[0]);
       clon.fst = (T)dupl; 
     } catch ( NoSuchMethodException e) {
      // exception suppressed
     } catch ( Exception e) {
       throw new InternalError (e.toString()); 
     }
     ...
}
In the exception handling suggested above we suppress the NoSuchMethodException under the assumption that an object without a clone method need not be cloned, but can be shared. 

Note, that we cannot ascertain statically by means of type argument bounds, that the members of a triple have a clone method.  We could define the type parameter with Cloneable as a bound, that is, as class Triple<T extends Cloneable> , but that would not avoid any of the issues discussed above.  The Cloneable interface is an empty tagging interface and does not demand that a cloneable type has a clone method.  We would still have to invoke the clone method via reflection and face the exception handling issues as before.

LINK TO THIS Practicalities.FAQ502
REFERENCES What is an "unchecked" warning?
What is the SuppressWarnings annotation?

 
 
 

Using Runtime Type Information

What does the type parameter of class java.lang.Class mean?

The type parameter is the type that the Class object represents, e.g. Class<String> represents String .
An object of type java.lang.Class represents the runtime type of an object.  Such a Class object is usually obtained via the getClass method defined in class Object . Alternative ways of obtaining a Class object representing a certain type are use of a class literal or the static method forName defined in class Class

Since Java 5.0 class java.lang.Class is a generic class with one unbounded type parameter. The type parameter is the type that the Class object represents.  For instance, type Number is represented by a Class object of type Class<Number> ,  type String by a Class object of type Class<String> , and so forth. 

Parameterized types share the same runtime type and as a result they are represented by  the same Class object, namely the Class object that represents the raw type.  For instance, all instantiations of List , such as List<Long> , List<String> , List<?> , and the raw type List itself are represented by the same Class object; this Class object is of type Class<List>

In general, the type argument of a Class object's type is the erasure of the type that the Class object represents. 

Note that the methods Object.getClass and Class.forName return references of a wildcard type. A side effect is that they cannot be assigned to a Class object of the actual type. 

Example (using Class objects): 

Number n = new Long(0L);
Class<Number> c1 = Number.class;
Class<Number> c2 = Class.forName("java.lang.Number"); // error
Class<Number> c3 = n.getClass();     // error
The forName method returns a reference of type Class<?> , not of type Class<Number> . Returning an object of any Class type makes sense because the method can return a Class object representing any type. 

The getClass method returns a reference of type Class<? extends X> , where X is the erasure of the static type of the expression on which getClass is called.  Returning Class<? extends X>   makes sense because the type X might be a supertype referring to a subtype object.  The getClass method would then return the runtime type representation of the subclass and not the representation of the supertype. In the example above the reference of type Number refers to an object of type Long , so that the getClass method returns a Class object of type Class<Long> instead of Class<Number>

Example (corrected): 

Number n = new Long(0L);
Class<Number>            c1 = Number.class;
Class<?>                 c2 = Class.forName("java.lang.Number"); 
Class<? extends Number>  c3 = n.getClass(); 
The easiest way of passing around type representations is via a reference of type Class<?> .
LINK TO THIS Practicalities.FAQ601
REFERENCES What is type erasure?
How do I pass type information to a method so that it can be used at runtime?

How do I pass type information to a method so that it can be used at runtime?

By means of a Class object.
The type information that is provided by a type parameter is static type information that is no longer available at runtime.  When we need type information that is available at runtime we must explicitly supply the runtime time information to the method.  Below are a couple of situations where the static type information provided by a type parameter does not suffice. 

Example (of illegal or pointless use of type parameter): 

public static <T> void someMethod() {
    ... new T() ... // error
    ... new T[ SIZE ] ... // error
    ... ref instanceof T ...      // error
    ... (T) ref .. .               // unchecked warning
  }
}


Utilities. <String> someMethod();
The type parameter T of the method does not provide any type information that would still be accessible at runtime.  At runtime the type parameter is represented by the raw type of it leftmost bound or type Object , if no bound was specified.  For this reason, the compiler refuses the accept type parameters in new expressions, and type checks based on the type parameter are either illegal or nonsensical. 

If we really need runtime type information we must pass it to the method explicitly.  There are 3 techniques for supplying runtime type information to a method:

  • supply an object 
  • supply an array 
  • supply a Class object
The 3 alternative implementations of the method above would look like this: 

Example (of passing runtime type information): 

public static <T> void someMethod( T dummy) { 
  Class<?> type = dummy.getClass();
  ...  use type reflectively ... 
}
public static <T> void someMethod( T[] dummy) { 
  ...  use type reflectively ... 
  Class<?> type = dummy.getClass().getComponentType();
}
public static <T> void someMethod( Class<T> type) { 
  ...  use type reflectively ... 
  ... (T)type.newInstance() ...
  ... (T[])Array.newInstance(type,SIZE) ...
  ... type.isInstance(ref) ...
  ... type.cast(tmp) ...
}


Utilities.someMethod( new String() ); 
Utilities.someMethod( new String[0] ); 
Utilities.someMethod( String.class );
The first two alternatives are wasteful, because dummy objects must be created for the sole purpose of supplying their type information. In addition, the first approach does not work when an abstract class or an interface must be represented, because no objects of these types can be created. 
The second technique is the classic approach; it is the one taken by the toArray methods of the collection classes in package java.util (see java.util.Collection.toArray(T[]) ). 
The third alternative is the recommended technique.  It provides runtime type information by means of a Class object. 

Here are the corresponding operations based on the runtime type information from the example above, this time performed using reflection. 

Example (of reflective use of runtime type information): 

public static <T> void som eMethod(Class<T> ty pe) { 
  ... (T)type.newInstance() ...
  ... (T[])Array.newInstance(type, SIZE ) ...
  ... type.isInstance( ref ) ...
  ... type.cast( tmp ) ...
}


Examples using class Class to provide type information can be found in the subsequent two FAQ entries (see REFERENCES or click here and here ).

LINK TO THIS Practicalities.FAQ602
REFERENCES What does the type parameter of class java.lang.Class mean?
How do I generically create objects and arrays?
How do I perform a runtime type check whose target type is a type parameter?

How do I generically create objects and arrays?
 
Using reflection.
The type information that is provided by a type parameter is static type information that is no longer available at runtime.  It does not permit generic creation of objects or arrays. 

Example (of failed generic array creation based on static type information): 

class Utilities {
  private static final int SIZE = 1024;

  public static <T> T[] createBuffer() {
    return new T[SIZE] ; // error
  }
}
public static void main(String[] args) {
  String[] buffer = Utilities. <String> createBuffer();
}

The type parameter T of method createBuffer does not provide any type information that would still be accessible at runtime.  At runtime the type parameter is represented by the raw type of it leftmost bound or type Object , if no bound was specified.  For this reason, the compiler refuses the accept type parameters in new expressions. 

If we need to generically create an object or array, then we must pass type information to the createBuffer method that persists until runtime. This runtime type information can then be used to perform the generic object of array creation via reflection. The type information is best supplied by means of a Class object. (A  Class object used this way is occasionally called a  type token .)

Example (of generic array creation based on runtime type information): 

public static <T> T[] createBuffer( Class<T> type) { 
  return (T[])Array.newInstance(type,SIZE);
}
public static void main(String[] args) { 
  String[] buffer = Utilities.createBuffer( String.class );
Note that the parameterization of class Class allows to ensure at compile time that no arbitrary types of Class objects are passed to the createBuffer method. Only a Class object that represents a runtime type that matches the desired component type of the created array is permitted.

Example: 

String[] buffer = Utilities.createBuffer( String.class );
String[] buffer = Utilities.createBuffer( Long.class ); // error
Number[] buffer = Utilities.createBuffer( Long.class );

Note also, that arrays of primitive type elements cannot be created using the aforementioned technique. 

Example (of a failed attempt to create an array of primitive type): 

class Utilities {
  @SuppressWarnings("unchecked")
  public static <T> T[] slice(T[] src, Class<T> type, int start, int length) {
    T[] result = (T[])Array.newInstance(type,length);
    System.arraycopy(src, start, result, 0, length);
    return result;
  }
}
class Test {
  public static void main(String[] args) {
    double[] avg = new double[]{1.0, 2.0, 3.0};
    double[] res = Utilities.slice(avg, double.class , 0, 2); // error
  }
}


error: <T>slice(T[],java.lang.Class<T>,int,int) cannot be applied to (double[],java.lang.Class<java.lang.Double>,int,int)
        double[] res = Utilities.slice(avg, double.class, 0, 2);
                       ^
Since primitive types are not permitted as type arguments, we cannot invoke the slice method using double.class as the type token.  The compiler would have to infer T:=double , which is not permitted because double is a primitive type and cannot be used as the type argument of a generic method.  The slice method can only create arrays of reference type elements, which means that we have to convert back and forth between double[] and Double[] in the example. 

Example (of a successful attempt to create an array of reference type): 

class Test {
  public static void main(String[] args) {
        double[] avg = new double[]{1.0, 2.0, 3.0};
       Double[] avgdup = new Double[avg.length];
        for (int i=0; i<avg.length;i++) avgdup[i] = avg[i];  // auto-boxing
       Double[] tmp = Utilities. slice(avgdup, Double.class , 0, 2);  // fine
        avg = new double[tmp.length];
        for (int i=0; i<tmp.length;i++) avg[i] = tmp[i];     // auto-unboxing
  }
}
LINK TO THIS Practicalities.FAQ603
REFERENCES What does the type parameter of class java.lang.Class mean?
How do I pass type information to a method so that it can be used at runtime?
Are primitive types permitted as type arguments?

How do I perform a runtime type check whose target type is a type parameter?
 
Using reflection.
The type information that is provided by a type parameter is static type information that is no longer available at runtime.  It does not permit any generic type checks. 

Consider a method that is supposed to extract from a sequence of objects of arbitrary types all elements of a particular type. Such a method must at runtime check for a match between the type of each element in the sequence and the specific type that it is looking for.  This type check cannot be performed by means on the type parameter. 

Example (of failed generic type check based on static type information): 

class Utilities {
  public static <T> Collection<T> extract(Collection<?> src) {
    HashSet<T> dest = new HashSet<T>();
    for (Object o : src)
      if (o instanceof T )     // error
         dest.add( (T) o);      // unchecked warning
    return dest;
  }
}
public static void test(Collection<?> coll) {
  Collection<Integer> coll = Utilities. <Integer> extract(coll);
}
Type parameters are not permitted in instanceof expressions and the cast to the type parameter is nonsensical, because it is a cast to type Object after type erasure. 

For a type check at runtime we must explicitly provide runtime type information so that we can perform the type check and cast by means of reflection.  The type information is best supplied by means of a Class object. 

Example (of generic type check based on runtime type information): 

class Utilities {
  public static <T> Collection<T> extract(Collection<?> src, Class<T> type) {
    HashSet<T> dest = new HashSet<T>();
    for (Object o : src)
      if ( type.isInstance(o)
         dest.add( type.cast(o) );
    return dest;
  }
}
public static void test(Collection<?> coll) {
  Collection<Integer> coll = Utilities.extract(coll, Integer.class );
}
LINK TO THIS Practicalities.FAQ604
REFERENCES What does the type parameter of class java.lang.Class mean?
How do I pass type information to a method so that it can be used at runtime?

Reflection

Which information related to generics can I access reflectively?

The exact static type information, but only inexact dynamic type information.
Using the reflection API of package java.lang.reflect you can access the exact declared type of fields, method parameters and method return values.  However, you have no access to the exact dynamic type of an object that a reference variable refers to. 

Below are a couple of examples that illustrate which information is available by means of reflection.  Subsequent FAQ entries discuss in greater detail the ways and means of extracting the information.  Here is the short version of how the static and dynamic type information is retrieved reflectively.

For illustration, we consider the field of a class:

Example (of a class with a field):

class SomeClass {
  static Object field = new ArrayList<String>();
  ...
}
The information regarding the declared type of a field ( static type information ) can be found like this:

Example (find declared type of a field):

class Test {
  public static void main(String[] args) {
    Field    f = SomeClass.class. getDeclaredField ("field");
    Type     t = f. getGenericType ();
  }
}
In order to retrieve the declared type of a field you need a representation of the field in question as an object of type java.lang.reflect.Field .  Such a representation can be found by invoking either the method getField() or getDeclaredField() of class java.lang.Class .  Class java.lang.reflect.Field has a method named getGenericType() ; it returns an object of type java.lang.reflect.Type , which represents the declared type of the field.

The information regarding the type of the object that a reference refers to ( dynamic type information ) can be found like this:

Example (find actual type of a field):

class Test {
  public static void main(String[] args) {
    Class<?> c = SomeClass.field. getClass ();
  }
}
In order to retrieve the actual type of an object you need a representation of its type as an object of type java.lang.Class . This type representation can be found by invoking the method getClass() of class java.lang.Object

In the example above, the field SomeClass.field is declared as a field of type Object ; for this reason Field.getGenericType() yields the type information Object .  This is the static type information of the field as declared in the class definition.

At runtime the field variable SomeClass.field refers to an object of any subtype of Object .  The actual type of the referenced object is retrieved using the object's getClass() method, which is defined in class Object . If the field refers to an object of type ArrayList<String> then getClass() yields the raw type information ArrayList , but not the exact type information ArrayList<String>

The table below shows further examples of the type information that is available for the field of a class using Field.getGenericType() and Object.getClass() .
 
Declaration of Field
(retrieved via Class.getField() )
Static Type Information
(retrieved via Field.getGenericType() )
Dynamic Type Information
(retrieved via Object.getClass() )
class SomeClass {
  Object field
  = new ArrayList<String> ();
  ...
}
Object regular type ArrayList generic type
class SomeClass {
  List<String> field 
  = new ArrayList<String> ();
  ...
}
List<String> parameterized type ArrayList generic type
class SomeClass {
  Set<? extends Number> field
  = new TreeSet<Long> ();
  ...
}
Set<? extends Number>  parameterized type TreeSet generic type
class SomeClass<T> {
  T field;
  SomeClass(T t) { field = t; }
  ...
}
SomeClass<CharSequence> object 
= new SomeClass<CharSequence>( "a" );
T type variable String non-generic type
class SomeClass {
  Iterable<?>[] field 
  = new Collection<?>[0] ;
  ...
}
Iterable<?>[] generic array type [LCollection non-generic type
class SomeClass<T> {
  T[] array;
  SomeClass(T... arg) { array = arg; }
  ...
}
SomeClass<String> object 
= new SomeClass<String>( "a" );
T[] generic array type [LString non-generic type

LINK TO THIS Practicalities.FAQ701
REFERENCES java.lang.reflect.Field.getGenericType()
java.lang.Object.getClass()

How do I retrieve an object's actual (dynamic) type?
 
By calling its getClass() method.
When you want to retrieve an object's actual type (as opposed to its declared type) you use a reference to the object in question and invoke its getClass() method. 

Example (of retrieving an object's actual type):

class Test {
  public static void main(String[] args) {
    Object tmp = java.util.EnumSet.allOf(java.util.concurrent.TimeUnit.class);
    Class<?> clazz = tmp. getClass() ;
    System.out.println("actual type of Object tmp is: "+clazz); 
  }
}

actual type of Object tmp is: class java.util.RegularEnumSet
The actual type of the object that the local tmp variable refers to is unknown at compile time. It is some class type that extends the abstract EnumSet class; we do not know which type exactly.  It turns out that in our example the actual type is java.util.RegularEnumSet , which is an implementation specific class type defined by the JDK implementor.  The class is a private implementation detail of the JDK and is not even mentioned in the API description of the java.util package.  Nonetheless the virtual machine can retrieve the actual type of the object via reflection by means of the getClass() method.

In contrast, the declared type of the object in question is type Object , because the reference variable tmp is of type Object

In this example the declared type is not available through reflection, because tmp is a local variable.  The declared type is available reflectively solely for fields of types, and for return types or parameter types or exception types of methods.  The actual type of an object, however, can be retrieved for all objects regardless of their declaration:  for local variables, fields of classes, return types of methods, arguments passed to method, etc.

The getClass() method of class Object returns an object of type java.lang.Class , which means that the actual type of each object is represented by a Class object.  You can extract various information about the type represented by the Class object, such as "is it a primitive type?", "is it an array type?", "is it an interface, or a class, or an enum type?", "which fields does the type have?", "which methods does the type have?", etc. You can additionally find out whether  the Class object represents a generic type by asking it: "does it have type parameters?".
 

LINK TO THIS Practicalities.FAQ702
REFERENCES How do I figure out whether a type is a generic type?
What is a parameterized or generic type?
How do I retrieve an object's declared type?
java.lang.Class

How do I retrieve an object's declared (static) type?
 
By finding the declaration's reflective representation and calling the appropriate getGeneric...() method.
When you want to retrieve an object's declared type (as opposed to its actual type) you first need a representation of the declaration. 
  • Field. For a field of a type you need a representation of that field in terms of an object of type java.lang.reflect.Field .  This can be obtained by one of the methods getField() , getFields() , getDeclaredField() , or getDeclaredFields() of class Class .
  • Return Value.  For the return value of a method you need a representation of the method in terms of an object of type java.lang.reflect.Method .  This can be obtained by one of the methods getMethod() , getMethods() , getDeclaredMethod() , or getDeclaredMethods() of class Class . Then you invoke the getGenericReturnType() method of class Method .
  • Method Parameter.   Same as for the return value.  Once you have a representation of the method, you invoke the getGenericParameterTypes() method of class Method .
  • Method Exceptions.   Same as for the return value.  Once you have a representation of the method, you invoke the getGenericExceptionTypes() method of class Method .
Note, that there is no representation of the declaration of a local variable on the stack of a method. Only the declarations of fields declared in classes, interfaces or enumeration types, and return types, parameter types, and exception types of methods have a reflective representation.

Example (of retrieving a field's declared type):

class Test {
  private static EnumSet<TimeUnit> set = EnumSet.allOf(TimeUnit.class);

  public static void main(String[] args) {
    Field field = Test.class. getDeclaredField ("set");
    Type type   = field. getGenericType ();
    System.out.println("declared type of field set is: "+type); 
  }
}


declared type of field set is: java.util.EnumSet<java.util.concurrent.TimeUnit>
The declared return type, argument type, or exception type of a method is retrieved similarly by invoking the corresponding getGeneric...Type() method.

All these methods return an object of type java.reflect.Type , which means that the declared type of an object is represented by a Type object.  Type is an interface and represents all type-like constructs in Java reflection.  It has five subtypes, as shown in the subsequent diagram.

Figure: Subtypes of Interface java.lang.reflect.Type

As you can tell from the diagram,  class Class is a subtype of interface Type , but it is not the only subtype.  A Type can represent one of the following type-like things:

  • A regular type .  In this case the Type variable refers to a Class object.  Examples of regular types are non-generic types such String or CharSequence , enumeration types such as TimeUnit , array types with regular component types such as String[] (but not   Class<?>[] , because the component type is a parameterized type), and raw types such as List or Set . In other words, a regular type is a type that has nothing to do with generics.
  • A parameterized type.  In this case the Type variable refers to an object of the subtype ParameterizedType . Examples of parameterized types are List<String> or Set<? extends Number> or Iterator<E> , that is, all types that are instantiations of generic types and have type arguments.
  • A type variable.  In this case the Type variable refers to an object of the subtype TypeVariable . Examples of  type variabes are T , E , K , V , that is, the type parameters of generic types and generic methods.
  • A generic array type.  In this case the Type variable refers to an object of the subtype GenericArrayType . Examples of generic array types are  Class<?>[] or T[] or Future<Object>[] or Iterator<?>[][] , that is, all array types with a non-regular component type.
  • A wildcard type.  In this case the Type variable refers to an object of the subtype WildcardType . Examples of wildcard types are ? or ? extends Number or ? super T , that is, all wildcard expressions.  If you retrieved the declared type of a field or the return type, argument type or exception type of a method, the resulting Type variable can never refer to a WildcardType , because wildcards are not types; they can only be used as type arguments. Hence, the subtype's name "wildcard type" is slightly misleading.  Only when you retrieve the type argument of a parameterized type you might come across a Type variable that refers to a WildcardType . This would, for instance, happen if you ask for the type argument of the type Class<?> .
Extracting information from the Type object returned by Field.getGenericType() or a similar method is not as easy as it is to retrieve information from a Class object.   When you have a Class variable you simply invoke methods of class Class .  When you have a Type variable you cannot invoke any methods, because the Type interface is an empty interface.  Before you can extract any information you must figure out to which of the 5 subtypes discussed above the Type variable refers.  This is usually done by a cascade of instanceof tests.

Example (of analyzing java.lang.reflect.Type ):

void analyzeType( Type type) {
         if ( type instanceof Class ) {
     // regular type, e.g. String or Date[]
  } else if ( type instanceof ParameterizedType ) {
     // parameteriezd type, e.g. List<String> or Set<? extends Number>
  } else if ( type instanceof TypeVariable ) {
     // type variable, e.g. T
  } else if ( type instanceof GenericArrayType ) {
     // generic array, e.g. List<?>[] or T[]
  } else if ( type instanceof WildcardType ) {
     // wildcard, e.g. ? extends Number or ? super Long
  } else {
     // we should never get here
     throw new InternalError("unknown type representation "+type);
  }
}
Once you know what subtype of type Type the variable refers to, you simply cast down to the respective subtype and start retrieving information by invocation of the subtype's methods.  Just browse the respective type's JavaDoc; most methods are self-explanatory.  Here are some examples:
  • If it is a Class then you can pose the usual questions such as "are you a primitive type?", "are you an array type?", "are you an interface, or a class, or an enum type?", "which fields do you have?", "which methods do you have?",  "do you have type parameters?", etc.
  • If it is a ParameterizedType you can ask "what type arguments do you have?", "what is your raw type?", etc.
  • If it is a TypeVariable you can ask "which bounds do you have?", "which generic type do you belong to?", etc.
  • If it is a GenericArrayType you can ask "what is your component type?".
  • If it is a WildcardType you can as "what is your upper and lower bound?".
LINK TO THIS Practicalities.FAQ703
REFERENCES How do I retrieve an object's actual type?
java.lang.reflect.Type

What is the difference between a generic type and a parameterized type in reflection?
 
A generic type is represented by a Class object; a parameterized type is represented by a ParameterizedType object.
Generic and parameterized types are easily confused when you access them via reflection.
  • We say that a type is a generic type (as opposed to non-generic type) when it declares formal type parameters, that is, placeholders that can be replaced by type arguments.  For instance, java.util.List is a generic type because it is declared as interface List<E> { ... } and has one type parameter E .  In contrast, class java.util.Date is a non-generic type, because it is a plain, regular class type that does have formal type parameters. 
  • We talk of a parameterized type (as opposed to a raw type) when we mean an instantiation of a generic type where the formal type parameters are replaced by actual type arguments.  For instance, List<String> is a parameterized type where the type parameter E is replaced by String .  In constrast, List is a raw type. The same is true for Date
In order to illustrate the difference between generic and parameterized type, let us consider an example.  Say, we want to retrieve the declared and actual type of the private field header of class java.util.LinkedList .  The field is declared as follows:
public class LinkedList<E> {
  private transient Entry<E> header = new Entry<E>(null, null, null);
  ...
  private static class Entry<T> { ... }
}
where Entry is a nested generic type defined in class LinkedList and E is the LinkedList 's type parameter. 

The header field's declared type is Entry<E> and its actual type is Entry . This might be confusing at first sight, because the header field is declared as field of type Entry<E> and it actually refers to an object of type Entry<E> .  However, due to type erasure, actual types are always raw types, because type erasure drops all information regarding type arguments.  This mismatch between declared type and actual type adds to the confusion regarding the distinction between parameterized and generic types.

In our example, the header field's declared type is Entry<E> and Entry<E> is a parameterized type (as opposed to a raw type). This is because Entry<E> is an instantiation of the generic type Entry rather than the raw type Entry .
The header field's actual type is the raw type Entry (as a side effect of type erasure) and Entry is a generic type (as opposed to a non-generic type). This is because class Entry has a formal type parameter T .
 
Declaration of Field
(retrieved via Class.getField() )
Static Type Information
(retrieved via Field.getGenericType() )
Dynamic Type Information
(retrieved via Object.getClass() )
public class LinkedList<E> {
  private transient Entry<E> header 
  = new Entry<E> (null, null, null);
  ...
  private static class Entry<T> { ... }
}
Entry<E> parameterized type Entry generic type

Let us consider another example.  Say, we want to retrieve  the declared and actual type of the public field EMPTY_LIST   of class Collections . The field is declared as follows:

public class Collections {
  public static final List EMPTY_LIST = new EmptyList();
  ...
  private static class EmptyList extends AbstractList<Object> { ... }
}
where EmptyList is a nested type defined in class Collections

The EMPTY_LIST field's declared type is List and  its actual type is LinkedList.EmptyList

The EMPTY_LIST field's declared type List is not a parameterized type, because it does not have any type arguments; it is a raw type.  In turn, the raw type List is a generic type, because interface List has a formal type parameter E .
The EMPTY_LIST field's actual type LinkedList.EmptyList is a non-generic type (as opposed to a generic type), because it does not have any formal type parameters; it is just a plain, regular class type.
 
Declaration of Field
(retrieved via Class.getField() )
Static Type Information
(retrieved via Field.getGenericType() )
Dynamic Type Information
(retrieved via Object.getClass() )
public class Collections {
  public static final List EMPTY_LIST 
  = new EmptyList ();
  ...
  private static class EmptyList 
  extends AbstractList<Object> { ... }
}
List regular (raw) type EmptyList non-generic type

The starting point for retrieving information regarding parameterized and generic types is different. Being generic or non-generic is a property of a type that is represented by a Class object. In contrast, whether a type is parameterized or raw is a property of a type represented by a Type object.  As a result, we need a Class object  to distinguish between generic or non-generic and we need a Type object to distinguish between parameterized and raw .

The method below distinguishes between a parameterized and a raw type.  It needs a Type object for this distinction.

Example (of distinction between parameterized and raw type):

static boolean isParameterizedType( Type type) {
  if (type instanceof ParameterizedType)
     return true;
  else
     return false;
}
The methods below distinguish between a generic and a non-generic type.  The distinction regarding generic and non-generic requires a Class object.

Example (of distinction between generic and non-generic type):

static boolean isGenericType( Class<?> clazz) {
  TypeVariable<?>[] params = clazz.getTypeParameters();
  if (params != null && params.length > 0) {
     return true;
  }
  else {
     return false;
  }
}
static boolean isGenericType( Type type) {
  if (type instanceof Class && isGenericType((Class<?>)type))
     return true;
  else
     return false;
}
The overloaded version of the method that takes a Type object delegates to the other version of the method that takes a Class object, because only Class objects provide the information whether the type in question has type parameters (i.e. is generic), or not.
LINK TO THIS Practicalities.FAQ704
REFERENCES What is a parameterized or generic type?
Which information related to generics can I access reflectively?
What is type erasure?
How do I figure out whether a type is a generic type?
Which information is available about a generic type?
How do I figure out whether a type is a parameterized type?
Which information is available about a parameterized type?

How do I figure out whether a type is a generic type?
 
By asking it whether it has type parameters.
When you have the type representation of a type in form of a Class object then you can find out whether the type represents a generic type by retrieving its type parameters.  If it does not have any type parameters then the type is a non-generic type, otherwise it is a generic type.  Here is an example:

Example (of distinction between generic and non-generic type):

Object object = new LinkedHashMap<String,Number>();
Class<?> clazz = object.getClass() ;
TypeVariable<?>[] params = clazz.getTypeParameters() ;
if (params != null && params.length > 0) {
   System.out.println(clazz + " is a GENERIC TYPE");
   // generic type, e.g. HashSet
}
else {
   System.out.println(clazz + " is a NON-GENERIC TYPE");
   // non-generic type, e.g. String
}


class java.util.LinkedHashMap is a GENERIC TYPE
We obtain the Class object by calling the getClass() of an object. The Class object represents the type LinkedHashMap in our example.  Note that getClass() returns the actual dynamic type of an object and the actual dynamic type is always a raw type because of type erasure.

Then we retrieve the type parameters by callling getTypeParameters() .  If type parameters are returned then the type is a generic type, otherwise it is non-generic. 

LINK TO THIS Practicalities.FAQ705
REFERENCES What is a parameterized or generic type? 
What is the difference between a generic type and a parameterized type in reflection?

Which information is available about a generic type?
 
All the information that is available for regular types plus information about the generic type's type parameters.
A generic type is represented by a Class object.  For this reason we can retrieve all the information about a generic type that is also available for regular non-generic types, such as fields, methods, supertypes, modifiers, annotations, etc. Different from a non-generic type a generic type has type parameters. They can be retrieved by means of the getTypeParameters() method. 

Let us take a look at an example, namely the generic class EnumSet<E extends Enum<E>> .

Example (of retrieving information about a generic type):

Object object = new EnumMap<TimeUnit,Number>(TimeUnit.class);
Class<?> clazz = object.getClass();
TypeVariable<?>[] params = clazz. getTypeParameters() ;
if (params != null && params.length > 0) {
  System.out.println(clazz + " is a GENERIC TYPE with "+params.length+" type parameters");
  System.out.println();

  for (TypeVariable<?> typeparam : params) {
      System.out.println("\t"+typeparam); 
  }
}
else {
  System.out.println(clazz + " is a NON-GENERIC TYPE");
}



class java.util.EnumMap is a GENERIC TYPE with 2 type parameters
TYPE PARAMETERS:
 K
 V
LINK TO THIS Practicalities.FAQ706
REFERENCES How do I figure out whether a type is a generic type?
Which information is available about a type parameter?
java.lang.Class
java.lang.reflect.GenericDeclaration
java.lang.reflect.Type
java.lang.reflect.TypeVariable

How do I figure out whether a type is a parameterized type?
 
By asking whether the type representation is a ParameterizedType .
When you have the type representation of a type in form of a Type object then you can find out whether the type represents a parameterized type (as opposed to a raw type) by checking whether the type representation refers to an object of a type that implements the ParameterizedType interface.  Here is an example:

Example (of distinction between parameterized and regular (raw) type):

Method method = EnumSet.class.getMethod("clone");
System.out.println("METHOD: "+method.toGenericString());
Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType ) {
   System.out.println(returnType + " is a PARAMETERIZED TYPE");
} else  if (returnType instanceof Class) {
   System.out.println(returnType + " is a RAW TYPE");
} else { 
   System.out.println(returnType + " is something else");
}


METHOD: public java.util.EnumSet<E> java.util.EnumSet.clone()
java.util.EnumSet<E> is a PARAMETERIZED TYPE
First we retrieve the declared return type of the clone() method of class EnumSet . by calling the getGenericReturnType() method of class java.lang.reflect.Method . The resulting Type object represents the clone() method's return type, which in our example is EnumSet<E> .  Then we verify that the return type is a parameterized type by means of an instanceof test.
LINK TO THIS Practicalities.FAQ707
REFERENCES Which information is available about a parameterized type?

Which information is available about a parameterized type?
 
Information about the parameterized type's type arguments, its corresponding raw type, and its enclosing type if it is a nested type or inner class.
A parameterized type is represented by a ParameterizedType object.  A parameterized type has actual type arguments, a corresponding raw type, and you can find out which enclosing type the parameterized type belongs to if it a nested type or inner class.

Let us take a look at an example, namely the parameterized type EnumMap<K,V> , which we retrieve as the return type of the clone() method of class EnumMap ..

Example (of retrieving information about a parameterized type):

Method method = EnumMap.class.getMethod("clone");
System.out.println("METHOD: "+method.toGenericString());
Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType) {
   System.out.println(returnType + " is a PARAMETERIZED TYPE");

   ParameterizedType type = (ParameterizedType) returnType;

   Type rawType = type. getRawType() ;
   System.out.println("raw type  : " + rawType);

   Type ownerType = type. getOwnerType() ;
   System.out.println("owner type: " + ownerType
                + ((ownerType != null) ? "" : ", i.e. is a top-level type"));

   Type[] typeArguments = type. getActualTypeArguments() ;
   System.out.println("actual type arguments: ");
   for (Type t : typeArguments)
     System.out.println("\t" + t);



METHOD: public java.util.EnumMap<K, V> java.util.EnumMap.clone()
java.util.EnumMap<K, V> is a PARAMETERIZED TYPE
raw type  : class java.util.EnumMap
owner type: null, i.e. is a top-level type
actual type arguments: 
 K
 V
LINK TO THIS Practicalities.FAQ708
REFERENCES How do I figure out whether a type is a parameterized type?
java.lang.reflect.ParameteriezedType

How do I retrieve the representation of a generic method?
 
By retrieving the type erasure of the generic method.
Generic methods are retrieved like non-generic methods:  the getMethod() method of class Class is invoked providing a description of the method's type signature, that is, the name of the method and the raw types of the parameter types.  What we supply is a description of the method's type erasure; we need not specify in any way, that the method is a generic method.

As an example let us retrieve the representation of the generic toArray() method of interface Collection .  It is declared as:

interface Collection<E> {
  ...
  <T> T[]  toArray(T[] a) { ... }
}
Example (of retrieving the representation of a generic method):
Method method = Collection.class.getMethod("toArray", Object[].class );
System.out.println("METHOD: "+method.toGenericString());


METHOD: public abstract <T> T[] java.util.Collection.toArray(T[])
Note, that we did not mention whether we are looking for a generic or a non-generic method.  We just supplied the method name " toArray " and specified its parameter type as Object[] , which is the type erasure of the declared parameter type T[] .

Note, that there is some minor potential for confusion regarding the method description that is delivered by the resulting Method object.  In the example above, we retrieved the method description using the toGenericString() method of class Method

System.out.println("METHOD: "+method. toGenericString() );


METHOD: public abstract <T> T[] java.util.Collection.toArray(T[])
It describes the generic method's signature including information regarding its type parameter T .  Had we used the toString() method instead, the resulting method description had described the type erasure of the method. 
System.out.println("METHOD: "+method. toString() );


METHOD: public abstract java.lang.Object[] java.util.Collection.toArray(java.lang.Object[])
The confusing element here is the fact that toString() does not deliver a description of the method as it is declared, but of its type erasure.
LINK TO THIS Practicalities.FAQ709
REFERENCES How do I figure out whether a method is a generic method?
What is a generic declaration?

How do I figure out whether a method is a generic method?
 
By asking it whether it has type parameters.
Starting with the reflective representation of a method in form of a Method object you can find out whether the method is generic or non-generic by retrieving its type parameters.  (Note, we are looking for type parameters, not method parameters.) If the method does not have any type parameters then it is a non-generic method, otherwise it is a generic method. Here is an example:

Example (of distinction between generic and non-generic method):

Method method = Collection.class. getMethod ("toArray",Object[].class);
TypeVariable[] typeParams = method.getTypeParameters() ;
if (typeParams!=null && typeParams.length>0) {
   System.out.println(method.getName()+" is a GENERIC METHOD");
} else {
   System.out.println(method.getName() +" is a NON-GENERIC METHOD");
}


toArray is a GENERIC METHOD
We obtain the Method object by calling the getMethod() method of the Class object that represents the type whose method we are looking for. In our example the Method object represents the generic toArray() of interface Collection

Then we retrieve the type parameters by callling getTypeParameters() .  If type parameters are returned then the method is a generic method, otherwise it is non-generic. 

LINK TO THIS Practicalities.FAQ710
REFERENCES Which information is available about a generic method?
How do I figure out whether a type is a generic type?
What is a generic declaration?

Which information is available about a generic method?
 
All the information that is available for regular methods plus information about the generic method's type parameters.
A generic method is represented by a Method object.  For this reason we can retrieve all the information about a generic method that is also available for regular non-generic methods, such as return type, method parameter types, exception types, declaring class, modifiers, annotations, etc. Different from a non-generic method a generic method has type parameters. They can be retrieved by means of the getTypeParameters() method.  Type parameters are represented by TypeVariable objects. 

Let us take a look at an example, namely the generic method 
<T extends Object & Comparable<? super T>> T Collections.max(Collection<? extends T>) .

Example (of retrieving information about a generic method):

Method theMethod = Collections.class. getMethod ("max",Collection.class);
System.out.println("analyzing method: ");
System.out.println(theMethod.toGenericString()+"\n");

TypeVariable[] typeParams = theMethod. getTypeParameters ();
if (typeParams!=null && typeParams.length>0) {
   System.out.println("GENERIC METHOD");
   System.out.println("type parameters: ");
   for (TypeVariable v : typeParams) {
      System.out.println("\t"+v);
   }
} else {
   System.out.println("NON-GENERIC METHOD");
}
System.out.println();

Type type = theMethod. getGenericReturnType ();
System.out.println("generic return type of method "+theMethod.getName()+": " + type);
System.out.println();

Type[] genParamTypes = theMethod. getGenericParameterTypes ();
if (genParamTypes == null || genParamTypes.length == 0) {
   System.out.println("no parameters");
} else { 
   System.out.println("generic parameter types: ");
   for (Type t : genParamTypes) {
       System.out.println("\t"+t);
   }
}
System.out.println();

Type[] genExcTypes = theMethod. getGenericExceptionTypes ();
if (genExcTypes == null || genExcTypes.length == 0) {
   System.out.println("no exceptions");
} else { 
   System.out.println("generic exception types: ");
   for (Type t : genExcTypes) {
       System.out.println("\t"+t);
   }
}



analyzing method: 
public static <T> T java.util.Collections.max(java.util.Collection<? extends T>)

GENERIC METHOD
type parameters: 
 T

generic return type of method max: T

generic parameter types: 
 java.util.Collection<? extends T>

no exceptions

Do not confuse getParameterTypes() with getTypeParameters() .  The methods getParameterTypes() and getGenericParameterTypes() return the types of the method parameters; in our example the type Collection<? extends T> .  The method getTypedParameters() returns a generic method's type parameters; in our example the type parameter T .
LINK TO THIS Practicalities.FAQ711
REFERENCES How do I figure out whether a method is a generic method?
What is a generic declaration?
java.lang.reflect.Method
Which information is available about a type parameter?

Which information is available about a type parameter?
 
The type parameter's name, its bounds, and the generic type or method that the type parameter belongs to.
Type parameters of generic types and methods are represented by TypeVariable objects.  A type parameter has a name, bounds, and you can find out which generic type or method the type parameter belongs to.

Let us take a look at an example, namely the type parameter of the generic class EnumSet<E extends Enum<E>> .

Example (of retrieving information about a generic type):

Object object = new EnumMap<TimeUnit,Number>(TimeUnit.class);
Class<?> clazz = object.getClass();
TypeVariable<?>[] params = clazz. getTypeParameters() ;
if (params != null && params.length > 0) {
  System.out.println(clazz + " is a GENERIC TYPE with "+params.length+" type parameters");
  System.out.println();

  for (TypeVariable<?> typeparam : params) {
    System.out.println(typeparam + " is a TYPE VARIABLE");
    System.out.println("name  : " + typeparam. getName() );

    GenericDeclaration genDecl = typeparam. getGenericDeclaration() ;
    System.out.println("is type parameter of generic declaration: " + genDecl);

    Type[] bounds = typeparam. getBounds() ;
    System.out.println("bounds: ");
    for (Type bound : bounds)
      System.out.println("\t" + bound + "\n");
      System.out.println();
    }
  }
  else {
    System.out.println(clazz + " is a NON-GENERIC TYPE");
  }



class java.util.EnumMap is a GENERIC TYPE with 2 type parameters

K is a TYPE VARIABLE
name  : K
is type parameter of generic declaration: class java.util.EnumMap
bounds: 
 java.lang.Enum<K>

V is a TYPE VARIABLE
name  : V
is type parameter of generic declaration: class java.util.EnumMap
bounds: 
 class java.lang.Object

LINK TO THIS Practicalities.FAQ712
REFERENCES How do I figure out whether a method is a generic method?
What is a generic declaration?
java.lang.reflect.Method

What is a generic declaration?
 
Either a generic type or a generic method or a generic constructor.
In Java reflection a generic declaration is something that has type parameters, that is, either a generic type or a generic method or a generic constructor. A generic declaration is represented by the interface GenericDeclaration from the java.lang.reflect package. It provides access to the getTypeParameters() method, which is used to retrieve the type parameters of generic types, methods and constructors.  Consequently, the classes Class , Method and Constructor implement this interface.
 
 

Figure: Subtypes of Interface java.lang.reflect.GenericDeclaration

LINK TO THIS Practicalities.FAQ713
REFERENCES How do I figure out whether a method is a generic method?
java.lang.reflect.GenericDeclaration
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Constructor

What is a wildcard type?
 
A wildcard expression; it appears as the type argument of a parameterized type.
In Java reflection a wildcard type is a wildcard expression such as " ? extends Number ".  It is represented by an object of type java.lang.reflect.WildcardType and can appear solely as a type argument of a parameterized type. The term "wildcard type" is slightly misleading, because a wildcard is not a type like the return type of a method or the type of a field.  More correctly it is a type argument of a parameterized type.

Let us take a look at an example, namely the wildcards that appear in the signature of the generic method 

<T extends Object & Comparable< ? super T >> T Collections.max(Collection< ? extends T >)
The first wildcard appears in the bounds of the method's type parameter T ; its second bound is Comparable<? super T> , which is a parameterized type, and its type argument is the wildcard " ? super T ".  The second wildcard appears in the method's declared argument type Collection<? extends T> , which is a parameterized type, and its type argument is the wildcard " ? extends T ". 

Here is how the wildcard in the bound is retrieved:

Example (of a wildcard in Java reflection):

Method method = Collections.class. getMethod ("max",Collection.class);
System.out.println("METHOD: "+method.toGenericString());

TypeVariable<Method> typeParameter = method. getTypeParameters ()[0];
System.out.println("TYPE PARAMETER: "+typeParameter);

ParameterizedType bound = (ParameterizedType)typeParameter. getBounds ()[1];
System.out.println("TYPE PARAMETER BOUND: "+bound);

WildcardType wildcard = ( WildcardType )bound. getActualTypeArguments ()[0];
System.out.println("WILDCARD: "+wildcard);



METHOD: public static <T> T java.util.Collections.max(java.util.Collection<? extends T>)
TYPE PARAMETER: T
TYPE PARAMETER BOUND: java.lang.Comparable<? super T>
WILDCARD: ? super T
We retrieve the method Collections.max via Class.getMethod() and its type parameter T via GenericDeclaration.getTypeParameters() .  The result is the representation of the generic method`s type parameter T as an object of type java.lang.reflect.TypeVariable.  W e retrieve the type variable's two bounds via TypeVariable.getBounds() . The second bound is Comparable<? super T> and it is represented by an object of type java.lang.reflect.ParameterizedType . W e retrieve its type argument ? super T via ParameterizedType.getActualTypeArguments() and check whether the type argument is a wildcard expression by checking whether it is represented by an object of type java.lang.reflect.WildcardType .

Here is how the wildcard in the declared method parameter type is retrieved:

Example (of a wildcard in Java reflection):

Method method = Collections.class. getMethod ("max",Collection.class);
System.out.println("METHOD: "+method.toGenericString());

ParameterizedType methodParameterType = (ParameterizedType)method. getGenericParameterTypes ()[0];
System.out.println("METHOD PARAMETER TYPE: "+methodParameterType); 

WildcardType wildcard = (WildcardType)methodParameterType. getActualTypeArguments ()[0];
System.out.println("WILDCARD: "+wildcard); 



METHOD: public static <T> T java.util.Collections.max(java.util.Collection<? extends T>)
METHOD PARAMETER TYPE: java.util.Collection<? extends T>
WILDCARD: ? extends T
We obtain a representation of the method as before and this time retrieve the type of its method parameter Collection<? extends T> via Method.getGenericParameterTypes() .  The result is the representation of the parameterized type Collection<? extends T> as an object of type java.lang.reflect.ParameterizedType.  W e retrieve its type argument ? extends T via ParameterizedType.getActualTypeArguments() and check whether the type argument is a wildcard expression by checking whether it is represented by an object of type java.lang.reflect.WildcardType .
LINK TO THIS  #FAQ714
REFERENCES Which information is available about a wildcard?

Which information is available about a wildcard?
 
The upper and the lower bound.
Wildcards can have an upper or a lower bound.  Consequently, a wildcard represented reflectively by an object of type java.lang.reflect.Wildcard supports retrieval of the bound.

For illustration, let us revisit the wildcards from the previous FAQ entry Practicalities.FAQ714 , namely the wildcards that appear in the method signature

<T extends Object & Comparable< ? super T >> T Collections.max(Collection< ? extends T >) .
Say, we retrieved a presentation of the wild " ? super T " as described in the previous FAQ entry Practicalities.FAQ714 . Then we can obtain it upper bound by calling the methods Wildcard.getLowerBounds() and Wildcard.getUpperBounds()

Example (of retrieving a wildcard's bound):

Method method = Collections.class.getMethod("max",Collection.class);
TypeVariable<Method> typeParameter = method.getTypeParameters()[0];
ParameterizedType bound = (ParameterizedType)typeParameter.getBounds()[1];
WildcardType wildcard = (WildcardType)bound.getActualTypeArguments()[0];
System.out.println("WILDCARD: "+wildcard);

Type[] lowerBounds = wildcard. getLowerBounds ();
System.out.print("lower bound: ");
if (lowerBounds != null && lowerBounds.length > 0) { 
   for (Type t : lowerBounds)
      System.out.println("\t" + t);
}
else {
   System.out.println("\t" + "<none>");
}
Type[] upperBounds = wildcard. getUpperBounds ();
System.out.print("upper bound: ");
if (upperBounds != null && upperBounds.length > 0) { 
   for (Type t : upperBounds)
      System.out.println("\t" + t);
}
else {
   System.out.println("\t" + "<none>");
}



WILDCARD: ? super T
lower bound:  T
upper bound:  class java.lang.Object
Interestingly, we can retrieve upper and lower bounds although a wildcard can have at most one bound - either an upper bound or a lower bound, but never both. 

The wildcard " ? super T " has a lower bound, but no upper bound.  Yet the getUpperBounds() method returns an upper bound, namely Object , which makes sense because Object can be seen as the default upper bound of every wildcard. 

Conversely, the wildcard " ? extends T " has an upper bound, but no lower bound.  The getLowerBounds() method returns a zero-length array in that case. 

This is illustrated by the wildcard in the method's parameter type Collection<? extends T> .  Say, we retrieved a presentation of the wild " ? extends T " as described in the previous FAQ entry Practicalities.FAQ714 . Then we can try out which bounds the methods Wildcard.getLowerBounds() and Wildcard.getUpperBounds() return.

Example (of retrieving a wildcard's bound):

Method method = Collections.class.getMethod("max",Collection.class);
ParameterizedType methodParameterType = (ParameterizedType)method.getGenericParameterTypes()[0];
WildcardType wildcard = (WildcardType)methodParameterType.getActualTypeArguments()[0];
System.out.println("WILDCARD: "+wildcard);

Type[] lowerBounds = wildcard. getLowerBounds ();
System.out.print("lower bound: ");
if (lowerBounds != null && lowerBounds.length > 0) { 
   for (Type t : lowerBounds)
      System.out.println("\t" + t);
}
else {
   System.out.println("\t" + "<none>");
}
Type[] upperBounds = wildcard. getUpperBounds ();
System.out.print("upper bound: ");
if (upperBounds != null && upperBounds.length > 0) { 
   for (Type t : upperBounds)
      System.out.println("\t" + t);
}
else {
   System.out.println("\t" + "<none>");
}



WILDCARD: ? extends T
lower bound:  <none>
upper bound:  T
LINK TO THIS Practicalities.FAQ715
REFERENCES What is a wildcard type?
java.lang.reflect.Wildcard



CONTENT PREVIOUS NEXT INDEX
  © Copyright 1995-2011 by Angelika Langer.  All Rights Reserved.    URL: < http://www.AngelikaLanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html  last update: 10 Aug 2011