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

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

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 - Type Parameters

Type Parameters

© Copyright 2004-2022 by Angelika Langer.  All Rights Reserved.
Fundamentals Type Parameter Bounds Usage Scope Static Context

Type Parameters

Fundamentals

What is a type parameter?

A place holder for a type argument.
Generic types have one or more type parameters. 

Example of a parameterized type: 

interface Comparable<E>  { 
  int compareTo(E other);
}
The identifier E is a type parameter. Each type parameter is replaced by a type argument when an instantiation of the generic type, such as Comparable<Object> or Comparable<? extends Number> , is used.
LINK TO THIS TypeParameters.FAQ001
REFERENCES How is a generic type defined?
What is a bounded type parameter?
Where is a type parameter visible (or invisible)?

What is a bounded type parameter?

A type parameter with one or more bounds.  The bounds restrict the set of types that can be used as type arguments and give access to the methods defined by the bounds.
When you declare a type parameter T and use it in the implementation of a generic type or method, the type parameter T still denotes an unknown type.  The compiler knows that T is a place holder for a type, but it does not know anything about the type.   This is okay in some implementations, but insufficient in others. 

Example (of a generic type without bounds): 

public class Hashtable<Key,Data> {
  ... 
  private static class Entry<Key,Data> {
    private Key key; 
    private Data value;
    private int hash;
    private Entry<Key,Data> next;
    ...
  }
  private Entry<Key,Data>[] table; 
  ... 
  public Data get(Key key) {
    int hash = key.hashCode() ;
    for (Entry<Key,Data> e = table[hash & hashMask]; e != null; e = e.next) {
      if ((e.hash == hash) && e. key.equals(key) ) {
        return e.value;
      }
    } 
    return null;
  }
}
The implementation of class Hashtable invokes the methods hashCode and equals on the unknown Key type.  Since hashCode and equals are methods defined in class Object and available for all reference types, not much need to be known about the unknown Key type.  This changes substantially, when we look into the implementation of sorted sequence. 

Example (of a generic type, so far without bounds): 

public interface Comparable<T> {
  public int compareTo(T arg);
}
public class TreeMap<Key,Data>{
  private static class Entry<K,V> {
     K key;
     V value;
     Entry<K,V> left;
     Entry<K,V> right;
     Entry<K,V> parent;
  }
  private transient Entry<Key,Data> root;
  ...
  private Entry<Key,Data> getEntry(Key key) {
     Entry<Key,Data> p = root;
     Key k = key;
     while (p != null) {
       int cmp = k. compareTo(p.key) ; // error
       if (cmp == 0)
         return p;
       else if (cmp < 0)
         p = p.left;
       else 
         p = p.right; 
     }
     return null;
  }
  public boolean containsKey(Key key) {
     return getEntry(key) != null;
  }
  ...
}
The implementation of class TreeMap invokes the method compareTo on the unknown Key type.  Since compareTo is not defined for arbitrary types the compiler refuses to invoke the compareTo method on the unknown type Key because it does not know whether the key type has a compareTo method. 

In order to allow the invocation of the compareTo method we must tell the compiler that the unknown Key type has a compareTo method.  We can do so by saying that the Key type implements the Comparable<Key> interface.  We can say so by declaring the type parameter Key as a bounded parameter. 

Example (of the same generic type, this time with bounds): 

public interface Comparable<T> {
  public int compareTo(T arg);
}
public class TreeMap<Key extends Comparable<Key> ,Data>{
  private static class Entry<K,V> {
     K key;
     V value;
     Entry<K,V> left = null;
     Entry<K,V> right = null;
     Entry<K,V> parent;
  }
  private transient Entry<Key,Data> root = null;
  ...
  private Entry<Key,Data> getEntry(Key key) {
     Entry<Key,Data> p = root;
     Key k = key;
     while (p != null) {
       int cmp = k. compareTo(p.key)
       if (cmp == 0)
         return p;
       else if (cmp < 0)
         p = p.left;
       else 
         p = p.right; 
     }
     return null;
  }
  public boolean containsKey(Key key) {
     return getEntry(key) != null;
  }
  ...
}
In the example above, the type parameter Key has the bound Comparable<Key> .  Specification of a bound has two effects: 
  • It gives access to the methods that the bound specifies .  In the example, the bound Comparable<Key> gives access to the compareTo method that we want to invoke in the implementation of our TreeMap class.
  • Only types "within bounds" can be used for instantiation of the generic type.   In the example, a parameterized type such as TreeMap<Number,String> would be rejected, because the type Number is not a subtype of Comparable<Number> .  A parameterized type like TreeMap<String,String> would be accepted, because the type String is within bounds, i.e. is a subtype of Comparable<String> .


Note that the suggested bound Comparable<Key> in this example is not the best conceivable solution.  A better bound, that is more relaxed and allows a larger set of type arguments, would be Comparable<? super Key> .  A more detailed discussion can be found in a separate FAQ entry (click here ).

LINK TO THIS TypeParameters.FAQ002
REFERENCES When would I use a wildcard parameterized with a lower bound?
What is a type parameter bound?
Which types are permitted as type parameter  bounds?
Can I use different instantiations of a same generic type as bounds of a type parameteer?
Does a bound that is a class type give access to all its public members?
Can I use a type parameter as part of its own bounds or in the declaration of other type parameters?

Type Parameter Bounds

What is a type parameter bound?

A reference type that is used to further describe a type parameter.  It restricts the set of types that can be used as type arguments and gives access to the non-static methods that it defines.
A type parameter can be unbounded.  In this case any reference type can be used as type argument to replace the unbounded type parameter in an instantiation of a generic type. 

Alternatively can have one or several bounds.  In this case the type argument that replaces the bounded type parameter in an instantiation of a generic type must be a subtype of all bounds. 

The syntax for specification of type parameter bounds is: 

<TypeParameter extends Class & Interface 1 & ... & Interface N >
A list of bounds consists of one class and/or several interfaces. 

Example (of type parameters with several bounds): 

class Pair<A extends Comparable<A> & Cloneable
           B extends Comparable<B> & Cloneable
  implements Comparable<Pair<A,B>>, Cloneable { ... }
This is a generic class with two type arguments A and B , both of which have two bounds.
LINK TO THIS TypeParameters.FAQ101
REFERENCES What is the difference between a wildcard bound and a type parameter bound?
Which types are permitted as type parameter  bounds?
Can I use different instantiations of a same generic type as bounds of a type parameteer?

Which types are permitted as type parameter  bounds?

All classes, interfaces and enum types including parameterized types, but no primitive types and no array types.
All classes, interfaces, and enum types can be used as type parameter bound, including nested and inner types.  Neither primitive types nor array types be used as type parameter bound. 

Examples (of type parameter bounds): 

class X0 <T extends int > { ... }      // error
class X1 <T extends Object[] > { ... } // error
class X2 <T extends Number > { ... }
class X3 <T extends String > { ... }
class X4 <T extends Runnable > { ... }
class X5 <T extends Thread.State > { ... }
class X6 <T extends List > { ... }
class X7 <T extends List<String> > { ... }
class X8 <T extends List<? extends Number> > { ... }
class X9 <T extends Comparable<? super Number> > { ... }
class X10<T extends Map.Entry<?,?> > { ... }
The code sample shows that primitive types such as int and array types such as Object[] are not permitted as type parameter bound. 

Class types, such as Number or String , and interface types, such as Runnable , are permitted as type parameter bound. 

Enum types, such as Thread.State are also permitted as type parameter  bound. Thread.State is an example of a nested type used as type parameter bound.  Non-static inner types are also permitted. 

Raw types are permitted as type parameter bound; List is an example. 

Parameterized types are permitted as type parameter bound, including concrete parameterized types such as List<String> ,  bounded wildcard parameterized types such as List<? extends Number> and Comparable<? super Long> , and unbounded wildcard parameterized types such as Map.Entry<?,?> .  A bound that is a wildcard parameterized type allows as type argument all types that belong to the type family that the wildcard denotes.  The wildcard parameterized type bound gives only restricted access to fields and methods; the restrictions depend on the kind of wildcard. 

Example (of wildcard parameterized type as type parameter bound): 

class X< T extends List<? extends Number> > {
  public void someMethod(T t) {
    t.add(new Long(0L));    // error
    Number n = t.remove(0);
  }
}
class Test {
  public static void main(String[] args) {
     X<ArrayList< Long >>   x1 = new X<ArrayList<Long>>(); 
     X<ArrayList< String >> x2 = new X<ArrayList<String>>(); // error
  }
}
Reference variables of type T (the type parameter) are treated like reference variables of a wildcard type (the type parameter  bound).  In our example the consequence is that the compiler rejects invocation of methods that take an argument of the "unknown" type that the type parameter stands for, such as List.add , because the bound is a wildcard parameterized type with an upper bound. 
At the same time the bound List<? extends Number> determines the types that can be used as type arguments. The compiler accepts all type arguments that belong to the type family List<? extends Number> , that is, all subtypes of List with a type argument that is a subtype of Number
 

Note, that even types that do not have subtypes, such as final classes and enum types, can be used as upper bound.  In this case there is only one type that can be used as type argument, namely the type parameter bound itself. Basically, the parameterization is pointless then. 

Example (of nonsensical parameterization): 

class Box< T extends String > {
  private T theObject;
  public Box( T t) { theObject = t; }
  ...
}
class Test {
  public static void main(String[] args) {
    Box< String > box1 = Box<String>("Jack");
    Box< Long >   box2 = Box<Long>(100L);    // error
  }
}
The compiler rejects all type arguments except String as "not being within bounds". The type parameter T is not needed and the Box class would better be defined as a non-parameterized class.
LINK TO THIS TypeParameters.FAQ102
REFERENCES What is a type parameter bound?
Can I use a type parameter as a type parameter bound?
Can I use different instantiations of a same generic type as bounds of a type parameter?
Can I use a type parameter as part of its own bounds or in the declaration of other type parameters?
How do unbounded wildcard instantiations of a generic type relate to other instantiations of the same generic type?
How do wildcard instantiations with an upper bound relate to other instantiations of the same generic type?
How do wildcard instantiations with a lower bound relate to other instantiations of the same generic type?
Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?

Can I use a type parameter as a type parameter bound?

Yes.
A type parameter can be used as the bound of another type parameter. 

Example (of a type parameter used as a type parameter bound): 

class Triple <T> {
  private T fst, snd, trd;
  public < U extends T , V extends T , W extends T > Triple(U arg1, V arg2, W arg3) {
    fst = arg1;
    snd = arg2;
    trd = arg3;
  }
}
In this example the type parameter T of the parameterized class is used as bound of the type parameters U V and W of a parameterized instance method of that class. 

Further opportunities for using type parameters as bounds of other type parameters include situations where a nested type is defined inside a generic type or a local class is defined inside a generic method.  It is even permitted to use a type parameter as bound of another type parameter in the same type parameter section.

LINK TO THIS TypeParameters.FAQ102A
REFERENCES Can I use a type parameter as part of its own bounds or in the declaration of other type parameters?
Which types are permitted as type parameter bounds?
Where is a type parameter visible (or invisible)?
Can I use different instantiations of a same generic type as bounds of a type parameteer?
What is the difference between a wildcard bound and a type parameter bound?

Can I use different instantiations of a same generic type as bounds of a type parameter?
 
No, at most one instantiation of the same generic type can appear in the list of bounds of a type parameter.
Example (of illegal use of two instantiations of the same generic type as bounds of a type parameter): 
class ObjectStore<T extends Comparable<T> & Comparable<String> > { // error 
  private Set<T> theObjects = new TreeSet<T> ();
  ...
  public boolean equals(ObjectStore<String> other) {
    if (theObjects.size() != other.size()) return false;
    Iterator<T> iterThis = theObjects.iterator();
    Iterator<String> iterOther = other.theObjects.iterator();
    while (iterThis.hasNext() && iterOther.hasNext()) {
      T t = iterThis.next();
      String string = iterOther.next();
      if ( t.compareTo(string) != 0)  return false;
    }
    return true;
  }
}


error: java.lang.Comparable cannot be inherited with different arguments: <T> and <java.lang.String>
    class ObjectStore<T extends Comparable<T> & Comparable<String>>  {
                      ^
In the example the type parameter T is required to be Comparable<T> , that is, comparable to its own type.  This is needed for storing objects of type T in a TreeSet<T> .  At the same time the type parameter T is required to be Comparable<String> , because we want to invoke the type parameter's compareTo(String) method. Remember, type parameter bounds are needed to give the compiler access to the type parameters non-static methods.  In this (admittedly contrived) example, we need to specify two instantiations of the Comparable interface as bound of the type parameter, but the compiler rejects it. 

The reason for this restriction is that there is no type that is a subtype of two different instantiations of the Comparable interface and could serve as a type argument.  It is prohibited that a type implements or extends two different instantiations of the same interface. This is because the bridge method generation process cannot handle this situation.  Details are discussed in a separate FAQ entry (click here ).  If no class can ever implement both instantiations of Comparable , there is no point to a bounds list that requires it.  The class in our example would not be instantiable because no type can ever be within bounds, except perhaps class String

In practice, you will need to work around this restriction. Sadly, there might be situations in  which there is no workaround at all.

LINK TO THIS TypeParameters.FAQ103
REFERENCES Can a class implement different instantiations of the same generic interface?
What is type erasure?
What is a bridge method?
How does type erasure work when a type parameter has several bounds?
How can work around the restriction that a type parameter cannot have different instantiations of a same generic type as its bounds?

How can I work around the restriction that a type parameter cannot have different instantiations of a same generic type as its bounds?
 
Usually there is no satisfactory workaround.
Let us use the example from the previous question for our search of a workaround. 

Example (of illegal use of two instantiations of the same generic type as bounds of a type parameter): 

class ObjectStore<T extends Comparable<T> & Comparable<String> > { // error
  pri vate Set<T> theObjects = new TreeSet<T> ();
  ...
  public boolean equals(ObjectStore<String> other) {
    if (theObjects.size() != other.size()) return false;
    Iterator<T> iterThis = theObjects.iterator();
    Iterator<String> iterOther = other.theObjects.iterator();
    while (iterThis.hasNext() && iterOther.hasNext()) {
      T t = iterThis.next();
      String string = iterOther.next();
      if ( t.compareTo(string) != 0)  return false;
    }
    return true;
  }
}
In the example the type parameter T is required to be Comparable<T> , because objects of type T are stored in a TreeSet<T> .  At the same time the type parameter T is required to be Comparable<String> , because we invoke the type parameter's compareTo(String) method. The compiler rejects the attempt of specifying two instantiations of the Comparable interface as bound of the type parameter. 

One workaround for the example above could be the following: we could  drop the requirement that the parameter T must be Comparable<T> , because the corresponding compareTo(T) method is not invoked in the implementation of the generic class itself, but in the operations of the Treeset<T> .  By dropping the requirement we would risk that a type argument is supplied that is not Comparable<T> and will cause ClassCastException s when operations of the TreeSet<T> are invoked.  Clearly not a desirable solution, but perhaps a viable one for this particular example. 

However, this might not be a solution if the class uses the type parameter in a slightly different way. For instance, if both compareTo methods were called in the implementation of the generic class, then we could not drop any of the bounds. 

Example (another class with illegal use of two instantiations of the same generic type as bounds of a type parameter): 

class SomeClass<T extends Comparable<T> & Comparable<String> > { // error 
  ... 
  private void method(T t1, T t2) {
     ... t1.compareTo(t2) ...
     ... t1.compareTo("string") ...
  }
}
If the methods of the bounds are invoked in the class implementation, then dropping one of the conflicting bounds does not solve the problem.  One could consider use of an additional interface, such as a CombinedComparable interface that combines the two required interfaces into one interface. 

Example (conceivable work-around; does not work): 

interface CombinedComparable<T> {
  int compareTo(T other);
  int compareTo(String other);
}
class SomeClass<T extends CombinedComparable<T>
  ... 
  private void m(T t1, T t2) {
     ... t1.compareTo(t2) ...
     ... t1.compareTo("string") ...
  }
  public boolean equals( SomeClass<String> other) {  // error 
    ...
  }
 }
However, this is not really a viable solution, because it excludes class String as a type argument. String is a class that is comparable to itself and to String , but it is does not implement a CombinedComparable interface. Hence type String is not within bounds. Another conceivable alternative is definition of one new interface per instantiation needed, such as a parameterized SelfComparable and a non-parameterized StringComparable interface.  Again, this excludes class String as a potential type argument.  If it acceptable that class String is excluded as a potential type argument then the definition of additional interfaces might be a viable workaround. 

But there remain some situations, in which additional interfaces do not help.  For instance, if the type parameter is used as type argument of another parameterized method, then it must itself be within the bounds of that other type parameter. 

Example (another class with illegal use of two instantiations of the same generic type as bounds of a type parameter): 

class AnUnrelatedClass {
  public static <T extends Comparable<String> > void f(T t) { ... }
}
class AnotherUnrelatedClass {
  public static <T extends Comparable<T> > void g(T t) { ... }
}
class SomeClass<T extends Comparable<T> & Comparable<String> > { // error 
  ... 
  private void h(T t) {
     AnUnrelatedClass.f(t);
     AnotherUnrelatedClass.g(t);
  }
}
No solution sketched out above would address this situation appropriately. If we required that the type parameter be CombinedComparable , it would not be within the bounds of at least one of the two invoked methods. Note, that the CombinedComparable interface can be a subinterface of only one of the two instantiations of Comparable , but not both. 

Example (conceivable work-around; does not work): 

interface CombinedComparable<T> extends Comparable<String> {
  int compareTo(T other);
}
class ObjectStore<T extends CombinedComparable<T>
  ... 
  private void h(T t) {
     AnUnrelatedClass.f(t); 
     AnotherUnrelatedClass.g(t); // error
  }
}
The same happens when we require that the type parameter be SelfComparable and StringComparable . Even if both were subinterfaces of the respective instantiation of Comparable , there cannot be a class that implements both, because that class would indirectly implement the two instantiations of Comparable

Ultimately the realization is that, depending on the circumstances, there might not be a work around at all.

LINK TO THIS TypeParameters.FAQ104
REFERENCES Can I use different instantiations of a same generic type as bounds of a type parameter?
Can a class implement different instantiations of the same parameterized interface?

Does a bound that is a class type give access to all its public members?

Yes, except any constructors.
A bound that is a class gives access to all its public members, that is, public fields, methods, and nested type. Only constructors are not made accessible, because there is no guarantee that a subclass of the bound has the same constructors as the bound. 

Example (of a class used as bound of a type parameter): 

public class SuperClass {

    // static members
    public enum EnumType {THIS, THAT}
    public static Object staticField;
    public static void staticMethod() { ... }

    // non-static members
    public class InnerClass { ... }
    public Object nonStaticField;
    public void nonStaticMethod() { ... }

    // constructors
    public SuperClass() { ... }

    // private members
    private Object privateField; 

    ...
}

public final class SomeClass<T extends SuperClass > {
    private T object;
    public SomeClass(T t) { object = t; } 

    public String toString() {
        return
         "static nested type    : "+T.EnumType.class+"\n" 
        +"static field          : "+T.staticField+"\n"
        +"static method         : "+T.staticMethod()+"\n"
        +"non-static nested type: "+T.InnerClass.class+"\n"
        +"non-static field      : "+object.nonStaticField+"\n"
        +"non-static method     : "+object.nonStaticMethod()+"\n"
        +"constructor           : "+(new T())+"\n"                    // error
        +"private member        : "+object.privateField+"\n"          // error 
        ;
    }
}

The bound SuperClass gives access to its nested types, static fields and methods and non-static fields and methods.  Only the constructor is not accessible.  This is because constructors are not inherited. Every subclass defines its own constructors and need not support its superclass's constructors.  Hence there is no guarantee that a subclass of SuperClass will have the same constructor as its superclass. 

Although a superclass bound gives access to types, fields and methods of the type parameter, only the non-static methods are dynamically dispatched. In the unlikely case that a subclass redefines types, fields and static methods of its superclass, these redefinitions would not be accessible through the superclass bound. 

Example (of a subclass of the bound used for instantiation): 

public final class SubClass extends SuperClass {
    // static members
    public enum Type {FIX, FOXI} 
    public static Object staticField;
    public static Object staticMethod() { ... }

    // non-static members 
    public class Inner { ... }
    public Object nonStaticField;
    public Object nonStaticMethod() { ... }

    // constructors 
    public SubClass(Object o) { ... }
    public SubClass(String s) { ... }

    ...
}



SomeClass< SubClass > ref = new SomeClass<SubClass>(new SubClass("xxx"));
System.out.println(ref);


prints:
static nested type    : SuperClass .EnumType
static field          : SuperClass .staticField
static method         : SuperClass .staticMethod  => SuperClass.staticField
non-static nested type: SuperClass .InnerClass
non-static field      : SuperClass .nonStaticField
non-static method     : SubClass .nonStaticMethod => SubClass.nonStaticField
Calling the nonStaticMethod results in invocation of the subclass's overriding version of the nonStaticMethod . In contrast, the subclass's redefinitions of types, fields and static methods are not accessible through the bounded parameter.  This is nothing unusual.  First, it is poor programming style to redefine in a subclass any of the superclass's nested types, fields and static methods.  Only non-static methods are overridden.  Second, the kind of hiding that we observe in the example above also happens when a subclass object is used through a superclass reference variable.
LINK TO THIS TypeParameters.FAQ105
REFERENCES

How do I decrypt "Enum<E extends Enum<E>>"?

As a type that can only be instantiation for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype arguments (or otherwise depend on the subtype).
The context in which " Enum<E extends Enum<E>> " appears is the declaration of the Enum class in package java.lang
public abstract class Enum<E extends Enum<E>> {
  ...
}
The type Enum is the common base class of all enumeration types.  In Java an enumeration type such as Color is translated into a class Color that extends Enum<Color> . The purpose of the superclass Enum is to provide functionality that is common to all enumeration types. 

Here is a sketch of class Enum

public abstract class Enum< E extends Enum<E>> implements Comparable< E >, Serializable {
  private final String name;
  public  final String name() { ... }

  private final int ordinal;
  public  final int ordinal() { ... }

  protected Enum(String name, int ordinal) { ... }

  public String           toString() { ... }
  public final boolean    equals(Object other) { ... }
  public final int        hashCode() { ... }
  protected final Object  clone() throws CloneNotSupportedException { ... }
  public final int        compareTo( E o) { ... }

  public final Class< E > getDeclaringClass() { ... }
  public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { ... }
}

The surprising feature in the declaration  " Enum<E extends Enum<E>> " is the fact that the newly defined class Enum and its newly defined type parameter E appear in the bound of that same type parameter.  It means that the Enum type must be instantiated for one of its subtypes.  In order to understand why this makes sense, consider that every enum type is translated into a subtype of Enum

Here is the contrived enum type Color

enum Color {RED, BLUE, GREEN}
The compiler translates it into the following class: 
public final class Color extends Enum<Color> {
  public static final Color[] values() { return (Color[])$VALUES.clone(); }
  public static Color valueOf(String name) { ... }

  private Color(String s, int i) { super(s, i); }

  public static final Color RED;
  public static final Color BLUE;
  public static final Color GREEN;

  private static final Color $VALUES[];

  static {
    RED = new Color("RED", 0);
    BLUE = new Color("BLUE", 1);
    GREEN = new Color("GREEN", 2);
    $VALUES = (new Color[] { RED, BLUE, GREEN });
  }
}

The inheritance has the effect that the Color type inherits all the methods implemented in Enum<Color> .  Among them is the compareTo method.  The Color.compareTo method should probably take a Color as an argument.  In order to make this happen class Enum is generic and the Enum.compareTo method takes Enum 's type parameter E as an argument.  As a result, type Color derived from Enum<Color> inherits a compareTo method that takes a Color as and argument, exactly as it should. 
 

If we dissect the declaration " Enum<E extends Enum<E>> " we can see that this pattern has several aspects. 

First, there is the fact that the type parameter bound is the type itself: " Enum <E extends Enum <E>> ". It makes sure that only subtypes of type Enum are permitted as type arguments. (Theoretically, type Enum could be instantiated on itself, like in Enum<Enum> , but this is certainly not intended and it is hard to imagine a situation in which such an instantiation would be useful.)

Second, there is the fact that the type parameter bound is the parameterized type Enum <E> ,  which uses the type parameter E as the type argument of the bound. This declaration makes sure that the inheritance relationship between a subtype and an instantiation of Enum is of the form " X extends Enum<X> ". A subtype such as " X extends Enum<Y> " cannot be declared because the type argument Y would not be within bounds; only subtypes of Enum<X> are within bounds.

Third, there is the fact that Enum is generic in the first place.  It means that some of the methods of class Enum take an argument or return a value of an unknown type (or otherwise depend on an unknown type). As we already know, this unknown type will later be a subtype X of Enum<X> .  Hence, in the parameterized type Enum<X> , these methods involve the subtype X , and they are inherited into the subtype X .  The compareTo method is an example of such a method; it is inherited from the superclass into each subclass and has a subclass specific signature in each case. 

To sum it up, the declaration " Enum<E extends Enum<E>> " can be decyphered as: Enum is a generic type that can only be instantiated for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype specific arguments (or otherwise depend on the subtype). 
 

LINK TO THIS TypeParameters.FAQ106
REFERENCES How is a generic type defined?
What is a bounded type parameter?
Where is a type parameter visible (or invisible)?

Why is there no lower bound for type parameters?

Because it does not make sense for type parameters of classes; it would occasionally be useful in conjunction with method declarations, though.
Type parameters can have several upper bounds, but no lower bound.  This is mainly because lower bound type parameters of classes would be confusing and not particularly helpful.  In conjunctions with method declarations, type parameters with a lower bound would occasionally be useful.  In the following, we first discuss lower bound type parameters of classes and subsequently lower bound type parameters of methods .


Lower Bound Type Parameters of Classes

Type parameters can have several bounds, like in class Box<T extends Number> {...} . But a type parameter can have no lower bound, that is, a construct such as class Box<T super Number> {...} is not permitted.  Why not?  The answer is: it is pointless because it would not buy you anything, were it allowed.  Let us see why lower bound type parameters of classes are confusing by exploring what a upper bound on a type parameter means. 

The upper bound on a type parameter has three effects: 

  1. Restricted Instantiation. The upper bound restricts the set of types that can be used for instantiation of the generic type.  If we declare a class Box<T extends Number> {...} then the compiler would ensure that only subtypes of Number can be used as type argument.  That is, a Box<Number> or a Box<Long> is permitted, but a Box<Object> or Box<String> would be rejected.

  2.  

     
     
     
     
     

    Example (of restricted instantiation due to an upper bound on a type parameter): 
     

      class Box<T extends Number> { 
         private T value; 
         public Box(T t) { value = t; } 
         ...
      class Test { 
         public static void main(String[] args) { 
             Box<Long>    boxOfLong   = new Box<Long>(0L);   // fine
             Box<String>  boxOfString = new Box<String>(""); // error: String is not within bounds
         }
      }
  3. Access To Non-Static Members. The upper bound gives access to all public non-static methods and fields of the upper bound.  In the implementation of our class Box<T extends Number> {...} we can invoke all public non-static methods defined in class Number , such as intValue() for instance.  Without the upper bound the compiler would reject any such invocation.Example (of access to non-static members due to an upper bound on a type parameter): 
      class Box<T extends Number> { 
         private T value; 
         public Box(T t) { value = t; } 
         public int increment() { return value.intValue()+1; } // <= would be an error without the Number bound
         ...
  1. Type Erasure. The leftmost upper bound is used for type erasure and replaces the type parameter in the byte code.  In our class Box<T extends Number> {...} all occurrences of T would be replaced by the upper bound Number .  For instance, if class Box has a private field of type T and a method void set(T content) for setting this private field, then the field would be of type Number after type erasure and the method would be translated to a method void set(Number content)

  2.  

     
     
     
     
     

    Example (of use of upper bound on a type parameter in type erasure - before type erasure): 
     

      class Box< T extends Number > { 
         private T value; 
         public Box( T t) { value = t; } 
         ...
    Example (of use of upper bound on a type parameter in type erasure - after type erasure): 
     
      class Box { 
         private Number value; 
         public Box( Number t) { value = t; } 
         ...
      }
    In addition, the leftmost upper bound appears in further locations, such as automatically inserted casts and bridge methods.


If lower bounds were permitted on type parameters, which side effects would or should they have? If a construct such as class Box<T super Number> {...} were permitted, what would it mean?  What would the 3 side effects of an upper type parameter bound  - restricted instantiation, access to non-static member, type erasure - mean for a lower bound? 

Restricted Instantiations. The compiler could restrict the set of types that can be used for instantiation of the generic type with a lower bound type parameter.  For instance, the compiler could permit instantiations such as Box<Number> and Box<Object> from a Box<T super Number> and reject instantiations such as Box<Long> or Box<Short> .  This would be an effect in line with the restrictive side-effect described for upper type parameter bounds. 

Access To Non-Static Members. A lower type parameter bound does not give access to any particular methods beyond those inherited from class Object . In the example of Box<T super Number> the supertypes of Number have nothing in common, except that they are reference types and therefore subtypes of Object .  The compiler cannot assume that the field of type T is of type Number or a subtype thereof.  Instead, the field of type T can be of any supertype of Number , such as Serializable or Object .  The invocation of a method such as intValue() is no longer type-safe and the compiler would have to reject it. As a consequence, the lower type parameter bound would not give access to an non-static members beyond those defined in class Object and thus has the same effect as "no bound". 

Type Erasure .  Following this line of logic, it does not make sense to replace the occurences of the type parameter by its leftmost lower bound.  Declaring a method like the constructor Box( T t) as a constructor Box( Number t) does not make sense, considering that T is replaces by a supertype of Number .  An Object might be rightly passed to the constructor in an instantiation Box<Object> and the constructor would reject it.  This would be dead wrong.   So, type erasure would replace all occurences of the type variable T by type Object , and not by its lower bound.  Again, the lower bound would have the same effect as "no bound". 

Do you want to figure out what it would mean if both lower _and_ upper bounds were permitted?   Personally, I do not even want to think about it and  would prefer to file it under "not manageable", if you permit. 

The bottom line is:  all that a " super " bound would buy you is the restriction that only supertypes of Number can be used as type arguments.  And even that is frequently misunderstood.  It would NOT mean, that class Box<T super Number> {...} contains only instances of supertypes of Number .  Quite the converse - as the example below demonstrates! 

Example (of use of upper bound on a type parameter in type erasure - before type erasure): 

class Box< T super Number > {
   private T value;
   public Box( T t) { value = t; }
   ...
}
Example (of use of upper bound on a type parameter in type erasure - after type erasure):
class Box {
   private Object value;
   public Box( Object t) { value = t; }
   ...
}
A class Box<T super Number> {...} would be translated by type erasure to a Box containing an Object field and it's constructor would be translated to Box(Object t) . That's fundamentally different from a class Box<T extends Number> {...} , which would be translated to a Box containing a Number field and it's constructor would be translated to Box(Number t) . Consequently, a Box<Number> instantiated from a class Box<T extends Number> {...} would be different from a Box<Number> instantiation from a class Box<T super Number> {...} , which is likely to cause confusion.  For this reason lower bounds do not make sense on type parameters of classes. 


Lower Bound Type Parameters of Methods

In conjunction with methods and their argument types, a type parameter with a lower bound can occasionally be useful.

Example (of a method that would profit from a type parameter with a lower bound):

class Pair<X,Y> {
   private X first;
   private Y second;
   ...
   public < A super X , B super Y > B addToMap(Map<A,B> map) {  // error: type parameter cannot have lower bound
      return map.put(first, second);
   }
}
class Test { 
   public static void main(String[] args) { 
     Pair<String,Long> pair = new Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Number number = pair.addToMap(map);
   }
}
The addToMap() method adds the content of the pair to a map.  Any map that can hold supertypes of X and Y would do.  The map's put() method returns the value found in the map for the given key, if there already is a key-value entry for the key in the map.  The return value of the map's put() method shall be returned from the addToMap() method.  Under these circumstances one would like to declare the method as shown above: The map is parameterized with supertypes of the pair's type parameters and the addToMap() method'S return type is the map's value type. 

Since the compiler does not permit lower bounds on type parameters we need a work-around. 

One work-around that comes to mind is use of a wildcard, because wildcards can have a lower bound.  Here is a work-around using a wildcard.

Example (of a work-around for the previous example using wildcards):

class Pair<X,Y> {
   private X first;
   private Y second;
   ...
   public Object addToMap(Map< ? super X , ? super Y > map) { 
      return map.put(first, second);
   }
}
class Test { 
   public static void main(String[] args) { 
     Pair<String,Long> pair = new Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Number number = (Number) pair.addToMap(map);
   }
}
It works, except that there is no way to declare the return type as desired.  It would be the supertype of Y that the compiler captures from the map type, but there is no syntax for specifying it.  We must not declare the return type a " ? super Y ", because " ? super Y " is a wildcard and  not a type and therefore not permitted as a return type. We have no choice and must use Object instead as our method's return type.  This rather unspecific return type in turn forces callers of the addToMap() method into casting the return value down from Object to its actual type.  This is not exactly what we had in mind.

Another work-around is use of static methods.  Here is a work-around with a static instead of a non-static method.

Example (of a work-around for the previous example using a static method):

class Pair<X,Y> {
   private X first;
   private Y second;
   ...
   public static < A , B ,X extends A ,Y extends B > B addToMap(Pair<X,Y> pair, Map< A , B > map) {
      return map.put(pair.first,pair.second);
   }
}
class Test { 
   public static void main(String[] args) { 
     Pair<String,Long> pair = new Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Number number = Pair .addToMap( pair ,map);
   }
}
The generic addToMap() method has four type parameters: two placeholders X and Y for the pair's type and two placeholders A and B for the map's type. A and B are supertypes of X and Y , because X and Y   are declared with A and B as their upper bounds. (Note, that the generic method's type parameters X and Y have nothing to do with the Pair class's X and Y parameters.  The names X and Y are reused for the generic method to make them easily recognizably as the pair's type parameters.)  Using four type parameters we can declare the precise return type as desired: it is the same type as the value type of the map.



The bottom line is that the usefulness of lower bounds on type parameters is somewhat debatable.  They would be confusing and perhaps even misleading when used as type parameters of a generic class.  On the other hand, generic methods would occasionally profit from a type parameter with a lower bound.   For methods, a work-around for the lack of a lower bound type parameter can often be found. Such a work-around typically involves a static generic method or a lower bound wildcard.
 
LINK TO THIS TypeParameters.FAQ107
REFERENCES What is a bounded type parameter?
Does a bound that is a class type give access to all its public members?
What is a bounded wildcard?
What is the difference between a wildcard bound and a type parameter bound?

Usage

Can I use a type parameter like a type?

No, a type parameter is not a type in the regular sense (different from a regular type such as a non-generic class or interface).
Type parameters can be used for typing (like non-generic classes and interfaces):: 
  • as argument and return types of methods
  • as type of a field or local reference variable 
  • as type argument of other parameterized types
  • as target type in casts 
  • as explicit type argument of parameterized methods
Type parameters can NOT be used for the following purposes (different from non-generic classes and interfaces):: 
  • for creation of objects 
  • for creation of arrays 
  • in exception handling
  • in static context
  • in instanceof expressions 
  • as supertypes
  • in a class literal
LINK TO THIS TypeParameters.FAQ200
REFERENCES

Can I create an object whose type is a type parameter?

No, because the compiler does not know how to create objects of an unknown type.
Each object creation is accompied by a constructor call. When we try to create an object whose type is a type parameter then we need an accessible constructor of the unknown type that the type parameter is a place holder for.  However, there is no way to make sure that the actual type arguments have the required constructors. 

Example (illegal generic object creation): 

public final class Pair< A , B > { 
    public final A fst;
    public final B snd;

    public Pair() {
       this.fst = new A() // error
       this.snd = new B() // error
    }
    public Pair(A fst, B snd) {
       this.fst = fst;
       this.snd = snd;
    }
}

In the example above, we are trying to invoke the no-argument constructors of two unknown types represented by the type parameters A and B .  It is not known whether the actual type arguments will have an accessible no-argument constructor. 

In situations like this - when the compiler needs more knowledge about the unknown type in order to invoke a method - we use type parameter bounds. However, the bounds only give access to methods of the type parameter. Constructors cannot be made available through a type parameter bound. 

If you need to create objects of unknown type, you can use reflection as a workaround.  It requires that you supply type information, typically in form of a Class object, and then use that type information to create objects via reflection. 

Example (workaround using reflection): 

public final class Pair <A,B>
    public final A fst;
    public final B snd;

    public Pair( Class<A> typeA, Class<B> typeB) {
       this.fst = typeA. newInstance();
       this.snd = typeB. newInstance();
    }
    public Pair(A fst, B snd) {
       this.fst = fst;
       this.snd = snd;
    }
}

LINK TO THIS TypeParameters.FAQ201
REFERENCES Does a bound that is a class type give access to all its methods and fields?
How do I generically create objects and arrays?
How do I pass type information to a method so that it can be used at runtime?

Can I create an array whose component type is a type parameter?

No, because the compiler does not know how to create an object of an unknown component type.
We can declare array variables whose component type is a type parameter, but we cannot create the corresponding array objects.  The compiler does not know how to create an array of an unknown component type. 

Example (before type erasure): 

class Sequence <T> {
  ... 
  public T[] asArray() {
    T[] array = new T[size] ; // error
    ...
    return array;
  }
}
Example (after a conceivable translation by type erasure): 
class Sequence {
  ... 
  public Object [] asArray() {
    Object [] array = new Object [size];
    ...
    return array;
  }
}
The type erasure of a type parameter is its leftmost bound, or type Object if no bound was specified. As a result, the compiler would create an array of Object s in our example.  This is not what we want.  If we later invoked the as Array method on a Sequence<String> a Object[] would be returned, which is incompatible to the String[] that we expect. 

Example (invocation of illegal method): 

S equence<String> seq = new Sequence<String>();
...
String[] arr = seq.asArray();            // compile-time error
String[] arr = (String[])seq.asArray();  // runtime failure: ClassCastException
Not even a ca st would help because the cast is guaranteed to fail at runtime.  The returned array is really an array of Object s, not just a reference of type Object[] refering to a String[]

If you need to create arrays of an unknown component type, you can use reflection as a workaround.  It requires that you supply type information, typically in form of a Class object, and then use that type information to create arrays via reflection. 

Example (workaround using reflection): 

class Sequence <T> {
  ... 
  public T[] asArray( Class<T> type) {
    T[] array = (T[])Array. newInstance(type,size) ; // unchecked cast
    ...
    return array;
  }
}
By the way, the unchecked warning is harmless and can be ignored. It stems from the need to cast to the unknown array type, because the newInstance method returns an Object[] as a result.
LINK TO THIS TypeParameters.FAQ202
REFERENCES What is type erasure?
How do I generically create objects and arrays?
How do I pass type information to a method so that it can be used at runtime?

Can I cast to the type that the type parameter stands for?

Yes, you can, but it is not type-safe and the compiler issues an "unchecked" warning.
Type parameters do not have a runtime type representation of their own. They are represented by their leftmost bound, or type Object in case of an unbounded type parameter. A cast to a type parameter would therefore be a cast to the bound or to type Object .

Example (of unchecked cast): 

class Twins<T> {
  public T fst,snd;
  public Twins(T s, T t) { fst = s; snd = t; }
  ...
}
class Pair<S,T> {
  private S fst;
  private T snd;
  public Pair(S s, T t) { fst = s; snd = t; }
  ... 
  public <U> Pair(Twins<U> twins) {
    fst = (S) twins.fst;        // unchecked warning
    snd = (T) twins.snd;        // unchecked warning
  }
}
The two casts to the type parameters are pointless because they will never fail; at runtime they are casts to type Object .  As a result any type of Pair can be constructed from any type of Twins . We could end up with a Pair<Long,Long> that contains String s instead of Long s.  This would be a blatant violation of the type-safety principle, because we would later trigger an unexpected ClassCastException , when we use this offensive Pair<Long,Long> that contains String s. In order to draw attention to the potentially unsafe casts the compiler issues "unchecked" warnings.
LINK TO THIS TypeParameters.FAQ203
REFERENCES What does type-safety mean?
What is type erasure?
What is the type erasure of a type parameter?

Can I use a type parameter in exception handling?

It depends. 
 Type parameters can appear in throws clauses, but not in catch clauses.
LINK TO THIS TypeParameters.FAQ204
REFERENCES Can I use a type parameter in a catch clause?
Can I use a type parameter in in a throws clause?
Can I throw an object whose type is a type parameter?

Can I derive from a type parameter?

No, because a type parameter does not have a runtime type representation of it own.
As part of the translation by type erasure, all  type parameters are replaces by their leftmost bound, or Object if the type parameter is unbounded.  Consequently, there is no point to deriving from a type parameter, because we would be deriving from its bound, not from the type that the type parameter stands for.  In addition, the actual type argument can be a final class or an enum type, from which we must not derive anyway. 

Example (of illegal derivation from type parameter; before type erasure): 

class Printable<T extends Collection<?>> extends T {    // illegal
  public void printElements(PrintStream out) { 
    for (Object o : this)  out.println(o);
  }
  public void printElementsInReverseOrder(PrintStream out) { 
    ... 
  }
}
final class Test {
  public static void main(String[] args) {
    Printable<LinkedList<String>> list = new Printable<LinkedList<String>>();
    list.add(2,"abc");
    list.printElements(System.out);
  }
}
The idea of this generic subclass is that it adds print functionality to all collection classes by means of derivation.  A Printable<LinkedList<String>> would have all the functionality of LinkedList<String> plus the print functionality. (This idiom is known in C++ as the curiously recurring template pattern ). Since it is illegal to derive from a type parameter, this kind of programming technique is not possible in Java. Consider what the subclass would look like after type erasure. 

Example (same example after a conceivable translation by type erasure): 

class Printable extends Collection {    // error: Collection is an interface, not class
  public void printElements( PrintStream out) { 
    for (Object o : this)  out.println(o);
  }
  public void printElementsInReverseOrder( PrintStream out) {
    ... 
  }
}

final class Test {
  public static void main(String[] args) {
    Printable list = new Printable();
    list.add(2,"abc");                   // error: no such method can be found in class Printable
    list.printElements(System.out);
  }
}

After type erasure the subclass Printable would not be a subclass of LinkedList , but a subclass of Collection , which is not even possible, because Collection is an interface, not a class.  Even if we used a class as the bound of the type parameter, such as <T extends AbstractCollection> , none of the list-specific methods would be available in the subclass, which entirely defeats the purpose of this programming pattern.
LINK TO THIS TypeParameters.FAQ205
REFERENCES What is type erasure?
Which types are permitted as type arguments?
The Curiously Recurring Template Pattern in C++ (James O. Coplien. A Curiously Recurring Template Pattern. In C++ Gems, 135-144. Cambridge University Press, New York, 1996)

Why is there no class literal for a type parameter?
 
Because a type parameter does not have a runtime type representation of its own.
As part of the translation by type erasure, all  type parameters are replaces by their leftmost bound, or Object if the type parameter is unbounded.  Consequently, there is no point to forming class literals such as T.class , where T is a type parameter, because no such Class objects exist.  Only the bound has a Class object that represents its runtime type. 

Example (before type erasure): 

<T extends Collection> Class<?> someMethod(T arg){
  ...
  return T.class;  // error
The compiler rejects the expression T.class as illegal, but even if it compiled it would not make sense.  After type erasure the method above could at best look like this:

Example (after type erasure): 

Class someMethod( Collection arg){
  ...
  return Collection .class;
The method would always return the bound's type representation, no matter which instantiation of the generic method was invoked.  This would clearly be misleading.

The point is that type parameters are non-reifiable , that is, they do not have a runtime type representation. Consequently, there is no Class object for type parameters and no class literal for them.

LINK TO THIS TypeParameters.FAQ206
REFERENCES What is type erasure?
What is a reifiable type?

 

Scope

Where is a type parameter visible (or invisible)?

Everywhere in the definition of a generic type or method, except any static context of a type.
Generic Classes

The scope of a class's type parameter is the entire definition of the class, except any static members or static initializers of the class. This means that the type parameters cannot be used in the declaration of static fields or methods or in static nested types or static initializers. 

Example (of illegal use of type parameter in static context of a generic class): 

class SomeClass <T> {
  // static initializer, static field, static method
  static {
    SomeClass< T > test = new SomeClass< T >(); // error
  }
  private static T globalInfo;          // error
  public  static T getGlobalInfo() {        // error
    return globalInfo;
  }
  // non-static initializer, non-static field, non-static method
  { 
    SomeClass< T > test = new SomeClass< T >();
  }
  private        T localInfo;
  public         T getLocalInfo() { 
    return localInfo;
  }
  // static nested types
  public static class Failure extends Exception {
    private final T info;          // error
    public Failure( T t) { info = t; }      // error
    public T getInfo() { return info; }    // error
   }
  private interface Copyable {
    T copy();                      // error
  }
  private enum State {
    VALID, INVALID;
    private T info; // error
    public void setInfo( T t) { info = t; } // error
    public T getInfo() { return info; }    // error
  }
  // non-static nested types
  public class Accessor {
    public T getInfo() { return localInfo; }
  }
}
The example illustrates that the type parameter cannot be used in the static context of a generic class.  It also shows that nested interfaces and enum types are considered static type members of the class.  Only inner classes, that is, non-static nested classes, can use the type parameter of the enclosing generic class. 

Generic Interfaces

The scope of an interface's type parameter is the entire definition of the interface, except any fields or nested types.  This is because fields and nested types defined in an interface are implicitly static. 

Example (of illegal use of type parameter in a generic interface): 

interface SomeInterface <T> {
  // field
  SomeClass< T > value = new SomeClass< T >();  // error
  // nested type
  class Accessor {
    public T getInfo() {            // error
      return value.getGlobalInfo();
    }
  }
  // methods
  T getValue();
}
The example shows that fields of an interface are implicitly static, so that the type parameter cannot be used anywhere in the declaration of a field of a generic interface.  Similarly, the nested class is considered a static nested class, not an inner class, and for this reason use of the type parameter anywhere in the nested class is illegal. 

Generic Methods

The scope of a method's or constructor's type parameter is the entire definition of the method; there is no exception, because a method has no static parts. 

Example (of use of type parameter in a generic method): 

private interface Copyable<T> {
  T copy();
}
// non-static method
<T extends Copyable<T>> void nonStaticMethod( T t) {
   final T copy = t.copy();

   class Task implements Runnable {
     public void run() {
       T tmp = copy;
       System.out.println(tmp);
     }
   }
   (new Task()).run();
}
// static method
static <T extends Copyable<T>> void staticMethod( T t) {
  final T copy = t.copy();

  class Task implements Runnable {
    public void run() {
       T tmp = copy;
       System.out.println(tmp);
    }
  } 
  (new Task()).run();
}

The example illustrates that the type parameter can be used any place in the definition of a generic method.  The type parameter can appear in the return and argument type.  It can appear in the method body and also in local (or anonymous) classes defined inside the method.  Note, that it does not matter whether the generic method itself is static or non-static.  Methods, different from types, do not have any "static context"; there is no such thing as a static local variable or static local class.
LINK TO THIS TypeParameters.FAQ301
REFERENCES Why can't I use a type parameter in any static context of the generic class?
Can I use a type parameter as part of its own bounds or in the declaration of other type parameters?

Can I use a type parameter as part of its own bounds?

Yes, the scope of a type parameter includes the type parameter section itself.
The type parameters of a generic type or method are visible in the entire declaration of the type or method, including the type parameter section itself. Therefore, type parameters can appear as parts of their own bounds, or as bounds of other type parameters declared in the same section. 

Example (of use of a type parameter in the type parameter section itself): 

public final class Wrapper < T extends Comparable < T >> implements Comparable<Wrapper<T>> {
  private final T theObject;
  public Wrapper(T t) { theObject = t; }
  public T getWrapper() { return theObject; }
  public int compareTo(Wrapper<T> other) { 
    return theObject.compareTo(other.theObject); 
  }
}
In the example above, the type parameter T is used as type argument of its own bound Comparable<T>

Example (of use of a type parameter in the type parameter section itself): 

< S ,T extends S > T create(S arg) { ... }
In the example above, the first type parameter S is used as bound of the second type parameter T
 

Forward references to type parameters are not permitted.  The type parameter cannot be used in the entire type parameter section, but only after its point of declaration. 

Example (of an illegal forward reference to a type parameter): 

< S extends T , T extends Comparable< S >> T create(S arg) { ... }  // error
In the example above, the type parameter T is used in the type parameter section before it has been defined in the same type parameter section.  This kind of forward reference is illegal. 
 

Forward references to types, not type parameters, are permitted, though. 

Example (of an forward reference to a type): 

interface Edge <N extends Node <? extends Edge<N>>> {
  N getBeginNode();
  void setBeginNode(N n);
  N getEndNode();
  void setEndNode(N n);
}
interface Node <E extends Edge <? extends Node<E>>> {
  E getOutEdge();
  void setOutEdge(E e);
  E getInEdge();
  void setInEdge(E e);
}
In the example above, the type Node is used (in the type parameter section of type Edge ) before it has been defined (probably in a different source file).  This kind of forward reference this permitted, which is not surprising. It is the usual way of defining and using types in Java.
LINK TO THIS TypeParameters.FAQ302
REFERENCES Where is a type parameter visible (or invisible)?
Can I use the type parameter of an outer type as part of the bounds of the type parameter of an inner type or a method?

Can I use the type parameter of an outer type as part of the bounds of the type parameter of an inner type or a method?
 
Yes, the type parameter of an enclosing generic type or method can be used in the type parameter section of an inner generic type or method.
The type parameters of a generic type or method can appear as parts of the bounds of the type parameters of any generic type or methods in that scope. 

Example (of use of type parameter of enclosing class in the type parameter section of a method): 

public final class Wrapper <T > {
  private final T theObject;
  public Wrapper(T t) { theObject = t; }
  public <U extends T > Wrapper(Wrapper<U> w) { theObject = w.theObject;}
  public T getWrapper() { return theObject; }
}
In the example above, the type parameter T of the class Wrapper<T> is used as bound of the type paramter U of the class's generic constructor. 

In principle, you can use the type parameters of a generic class anywhere in the class scope, including the type parameter sections of any generic methods or nested and inner types. For instance, the type parameters can appear in the type parameter declaration of  an inner class. 

Example (of use of type parameter of enclosing class in the type parameter section of an inner class): 

public final class Wrapper <T> {
  private final T theObject;
  public Wrapper(T t) { theObject = t; }
  public T getWrapper() { return theObject; }

  private final class WrapperComparator <W extends Wrapper<? extends Comparable< T >>
    implements Comparator<W> {
      public int compare(W lhs, W rhs) {
        return lhs.theObject.compareTo((T)(rhs.theObject));
      }
  }
  public <V extends Wrapper<? extends Comparable< T >> > Comparator<V> comparator() {
    return this.new WrapperComparator<V>();
  }
}

In this example, the type parameter T of the class Wrapper<T> is used as part of the bound of the type parameter W of inner class WrapperComparator . In addition, it is also used as part of the bound of the type parameter V of the comparator method. 

Similar rules apply to generic interfaces.  Even the type parameters of a generic method can be used in the declaration of the type parameters of a local generic type. 

Example (of use of type parameter of a method in the type parameter section of a local class): 

class Test {
  private static <T> void method() {
    class Local <A extends T > { ... }
    ...
  }
}
However, generic local classes are rather rare in practice.

The type parameters of a generic type or method can appear anywhere in the declaration of the type parameters of any generic type or methods in that scope.  A type parameter T can appear 

  • as the bound, as in <U extends T> , or 
  • as part of the bounds, as in <U extends Comparable<T>> , or 
  • as the bound of a wildcard, as in <U extends <Comparable<? super T>> , or 
  • as part of the bound of a wildcard, as in <U extends Wrapper<? extends Comparable<T>>> .
There is only one restriction: if a type parameter is used as the bound of another type parameter then there must not follow any further bounds. 

Example (of illegal use of type parameter as a bound):: 

class Wrapper<T> implements Cloneable {
  private final T theObject;
  ...
  public <U extends T & Cloneable > Wrapper<U> clone() { ... }     // error
}
The type parameter T is followed by another bound, which is illegal.
LINK TO THIS TypeParameters.FAQ303
REFERENCES Where is a type parameter visible (or invisible)?
Can I use a type parameter as part of its own bounds?

 
 

Static Context

Is there one instances of a static field per instantiation of a generic type?

No, there is only one instance of a static field for all instantiations of a generic type.
If a generic type has a static field, how many instances of this static field exist? 

Example (of a generic class with a static field): 

class SomeClass<T> {
  public static int count;
  ...
}
The generic type can be instantiated for an arbitrary number of type arguments. Is there a different instance of the static field for each instantiation of the generic type? 

Example (of several instantiations and usage of the static field(s)): 

SomeClass<String> ref1 = new SomeClass<String>();
SomeClass<Long>   ref2 = new SomeClass<Long>();

ref1.count++; 
ref2.count++; 

The question is: are we accessing two different static fields in the code snippet above? The answer is: no, there is only one instance of a static field per parameterized type, not several ones per instantiation of the generic type. 

The reason is that the compiler translates the definition of a generic type into one unique byte code representation of that type.  The different instantiations of the generic type are later mapped to this unique representation by means of type erasure . The consequence is that there is only one static count field in our example, despite of the fact that we can work with as many instantiations of the generic class as we like. 

Example (showing the syntax for access to a static field of a generic type): 

SomeClass<String> ref1 = new SomeClass<String>();
SomeClass<Long>   ref2 = new SomeClass<Long>();

ref1.count++;               // discouraged, but legal
ref2.coun t++;               // discouraged, but legal
SomeClass .count++; // fine, recommended
SomeClass<String>.count++;  // error
SomeClass<Long>.count++;    // error

Although we can refer to the static field through reference variables of different type, namely of type SomeClass<String> and SomeClass<Long> in the example, we access the same unique static count field.  The uniqueness of the static field is more clearly expressed when we refer to the static field using the enclosing scope instead of object references.  Saying SomeClass.count makes clear that there is only one static count field that is independent of the type parameters of the enclosing class scope.  Since the static field is independent of the enclosing class's type parmeters it is illegal to use any instantiation of the generic enclosing class as scope qualifier.
LINK TO THIS TypeParameters.FAQ401
REFERENCES What is type erasure?
How do I refer to static members of a parameterized type?
Where is a type parameter visible (or invisible)?
Why can't I use a type parameter in any static context of the generic class?

Why can't I use a type parameter in any static context of a generic class?
 
Because the static context is independent of the type parameters and exists only once per raw type, that is, only once for all instantiations of a generic type.
Type parameters must not appear in any static context of a generic type, which means that type parameters cannot be used in the declaration of static fields or methods or in static nested types or static initializers. 

Example (of illegal use of a type parameter in static context): 

public final class X <T> {
  private static T field;                       // error
  public  static T getField() { return field; }       // error
  public  static void setField( T t) { field = t; }    // error
}
The attempt of declaring a static field of the unknown type T is non-sensical and rightly rejected by the compiler. There is only one instance of the static field for all instantiations of the generic class. Of which type could that static field possibly be?  The declaration of a static field, whose type is the type parameter, makes it look like there were several instances of different types, namely one per instantiation, which is misleading and confusing.  For this reason, the use of type parameters for declaration of static fields is illegal. 

As static methods often operate on static fields it makes sense to extend the rule to static methods: the type parameter must not appear in a static method. 

Interestingly, the same rule applies to static nested types defined in a generic class. There is no compelling technical reason for this restriction.  It's just that static nested types are considered independent of any instantiations of the generic class, like the static fields and methods.  For this reason, use of the type parameter in a static nested type is illegal.   (Note, static nested types include nested static classes, nested interfaces and nested enum types.) 

Example (of illegal use of a type parameter in static context): 

class Wrapper <T> {
  private final T theObject;
  public Wrapper( T t) { theObject = t; }
  public T getWrappedItem() { return theObject; }

  public Immutable makeImmutable() {
        return new Immutable(theObject);
  }
  public Mutable makeMutable() {
        return new Mutable(theObject);
  }
  private static <A> A makeClone(A theObject) { ... }

  public static final class Immutable {
        private final T theObject;        // error

        public Immutable( T arg) {         // error
            theObject = makeClone(arg);
        }
        public T getWrappedItem() {       // error
            return makeClone(theObject);
        }
  }
  public static class Mutable {
        ... similar ...
  }
}

In the example above the type parameter is used in the context of a nested class type. The compiler rejects the use of the type parameter because the class type is a nested static class. 


Workaround for nested static classes and interfaces:

In case of static nested classes and interfaces this is not a major calamity.  As a workaround we can generify the static class or interface itself. 

Example (workaround - generify the nested static type): 

class Wrapper <T> {
  private final T theObject;
  public Wrapper( T t) { theObject = t; }
  public T getWrapper() { return theObject; }

  public Immutable <T> makeImmutable() {
        return new Immutable <T> (theObject);
  }
  public Mutable <T> makeMutable() {
        return new Mutable <T> (theObject);
  }
  private static <A> A makeClone(A theObject) { ... }

  public static final class Immutable <A> { // is a generic class now
        private final A theObject;

        public Immutable( A arg) {
            theObject = makeClone(arg);
        }
        public A getWrappedItem() {
            return makeClone(theObject);
        }
  }
  public static class Mutable <A> {
        ... similar ...
  }
}

There is no such workaround for nested enum type because they cannot be generic.
 

Workaround for nested static classes:

If the nested static type is a class, an alternative workaround would be turning the static class into an non-static inner class.

Example (workaround - use an inner class): 

class Wrapper <T> {
  private final T theObject;
  public Wrapper( T t) { theObject = t; }
  public T getWrapper() { return theObject; }

  public Mutable makeMutable() {
      return this. new Mutable(theObject);
  }
  public Immutable makeImmutable() {
      return this. new Immutable(theObject);
  }
  private static <A> A makeClone(A theObject) { ... }

  public final class Immutable {  // is no longer a static class
      private final T theObject;

      public Immutable( T arg) {
          theObject = makeClone(arg);
      }
      public T getWrappedItem() {
          return makeClone(theObject);
      }
  }
  public class Mutable 
        ... similar ...
  }
}

This workaround comes with a certain amount of overhead because all inner classes have a hidden reference to an instance of the outer type, which in this example they neither need nor take advantage of; the hidden reference is just baggage.  Often, inner classes are combined with interfaces in order to keep the inner class a private implementation detail of the enclosing class.  We can do the same here.

Example (the previous workaround refined): 

class Wrapper <T> {
  private final T theObject;
  public Wrapper( T t) { theObject = t; }
  public T getWrapper() { return theObject; }

  public Mutable <T> makeMutable() {
      return this.new Mutable(theObject);
  }
  public Immutable <T> makeImmutable() {
      return this.new Immutable(theObject);
  }
  private static <A> A makeClone(A theObject) { ... }

  public interface Immutable<S> {
      S getWrappedItem();
  }
  public interface Mutable<S> {
      S getWrappedItem();
      void setWrappedItem(S arg);
  }
  private final class ImmutableImplementation implements Immutable<T>

      private final T theObject;

      public ImmutableImplementation(T arg) {
          theObject = makeClone(arg);
      }
      public T getWrappedItem() {
          return makeClone(theObject);
      }
  }
  private class MutableImplementation implements Mutable<T>
        ... similar ...
  }
}

As you can see, the nested public interfaces need to be generic whereas the inner private classes can use enclosing class's the type parameter. 
LINK TO THIS TypeParameters.FAQ402
REFERENCES Where is a type parameter visible (or invisible)?
Is there one instances of a static field per instantiation of a generic type?



CONTENT PREVIOUS NEXT INDEX
  © Copyright 1995-2022 by Angelika Langer.  All Rights Reserved.    URL: < http://www.AngelikaLanger.com/GenericsFAQ/FAQSections/TypeParameters.html  last update: 14 Aug 2018