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).
is a type parameter. Each type parameter is replaced
by a type argument when an instantiation of the generic type, such as
Comparable<Object>
Comparable<? extends Number>
, is used.
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.
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) &&
key.equals(key)
return e.value;
return null;
The implementation of class
Hashtable
invokes the methods
hashCode
equals
on the unknown
type. Since
hashCode
equals
are methods defined in class
Object
and available for all reference
types, not much need to be known about the unknown
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;
p = p.right;
return null;
public boolean containsKey(Key key) {
return getEntry(key) != null;
The implementation of class
TreeMap
invokes the method
compareTo
the unknown
type. Since
compareTo
is not defined
for arbitrary types the compiler refuses to invoke the
compareTo
method on the unknown type
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
type has a
compareTo
method. We can do so by saying that the
type implements
Comparable<Key>
interface. We can say so by declaring
the type parameter
as a bounded parameter.
Example (of the same generic type, this time
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;
p = p.right;
return null;
public boolean containsKey(Key key) {
return getEntry(key) != null;
In the example above, the type parameter
has the bound
Comparable<Key>
Specification of a bound has two effects:
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>
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
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
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
extends
Comparable<B> & Cloneable
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
{ ... }
// error
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;
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>
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
(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
with a type argument that is a subtype
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
theObject;
public Box(
t) { theObject
= t; }
class Test {
public static void main(String[] args) {
String
box1 = Box<String>("Jack");
box2 = Box<Long>(100L);
error
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.
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
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.
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>
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
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
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>
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);
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 {
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);
Comparable
, there cannot be a class that implements
both, because that class would indirectly implement the two instantiations
Comparable
Ultimately the realization is that, depending on the circumstances,
there might not be a work around at all.
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 {
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.
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).
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
is to provide functionality that is common
to all enumeration types.
Here is a sketch of class
public abstract class
extends Enum<E>>
implements Comparable<
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(
o) { ... }
public final Class<
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
and its newly defined type parameter
appear
in the bound of that same type parameter. It means that the
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
Here is the contrived enum type
Color
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
compareTo
method. The
Color.compareTo
method
should probably take a
Color
as an argument. In order to
make this happen class
is generic and the
Enum.compareTo
method takes
's type parameter
as an argument.
As a result, type
Color
derived from
Enum<Color>
inherits
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: "
<E extends
It makes sure that only subtypes of type
are permitted as
type arguments. (Theoretically, type
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
which uses the type parameter
as the type argument of the bound.
This declaration makes sure that the inheritance relationship between a
subtype and an instantiation of
is of the form "
X extends
Enum<X>
". A subtype such as "
X extends Enum<Y>
" cannot
be declared because the type argument
would not be within bounds;
only subtypes of
Enum<X>
are within bounds.
Third, there is the fact that
is generic
in the first place. It means that some of the methods of class
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
Enum<X>
. Hence, in the parameterized
Enum<X>
, these methods involve the subtype
and they are inherited into the subtype
. 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:
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).
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
classes
and subsequently
lower bound type parameters of
methods
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:
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>
Box<Long>
is permitted, but a
Box<Object>
Box<String>
would be rejected.
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):
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
would
be replaced by the upper bound
Number
. For instance, if
class
has a private field of type
and a method
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)
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>
Box<Object>
from a
Box<T
super
Number>
and reject instantiations
such as
Box<Long>
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
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
is of type
Number
a subtype thereof. Instead, the field of type
can be of
any supertype of
Number
, such as
Serializable
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
as a constructor
Number
does not make sense,
considering that
is replaces by a supertype of
Number
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
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> {...}
, which
is likely to cause confusion. For this reason lower bounds do not
make sense on type parameters of classes.
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);
addToMap()
method adds the content of the pair to a map.
Any map that can hold supertypes of
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
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
extends
extends B
> B addToMap(Pair<X,Y> pair, Map<
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 =
.addToMap(
,map);
The generic
addToMap()
method has four type parameters: two placeholders
for the pair's type and two placeholders
the map's type.
are supertypes of
, because
are declared with
as their upper bounds. (Note, that the generic method's
type parameters
have nothing to do with the
class's
parameters. The names
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.
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).
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<
public final A fst;
public final B snd;
public Pair() {
this.fst =
// error
In the example above, we are trying to invoke the no-argument constructors
of two unknown types represented by the type parameters
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
public final A fst;
public final B snd;
public Pair(
Class<A>
typeA,
Class<B>
typeB) {
this.fst =
typeA.
newInstance();
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
public T[] asArray() {
T[] array =
new T[size]
error
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
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
public T[] asArray(
Class<T>
type) {
T[] array = (T[])Array.
newInstance(type,size)
unchecked cast
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.
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):
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
can be constructed from
any type of
Twins
We could end up with a
Pair<Long,Long>
that contains
String
s instead of
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>
contains
String
s. In order to draw attention to the potentially
unsafe casts the compiler issues "unchecked" warnings.
As part of the translation by type erasure, all type
parameters are replaces by their leftmost bound, or
Object
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
{ // 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>
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
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
extends AbstractCollection>
, none of the list-specific methods would
be available in the subclass, which entirely defeats the purpose of this
programming pattern.
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)
As part of the translation by type erasure, all type
parameters are replaces by their leftmost bound, or
Object
the type parameter is unbounded. Consequently, there is no point
to forming class literals such as
T.class
, where
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
Class
object for type parameters and no
class
literal
for them.
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
static initializer, static field, static method
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.
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
field
SomeClass<
> value
= new SomeClass<
error
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.
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
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.
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
extends Comparable
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):
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
extends
extends Edge<N>>>
) 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.
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
private final T theObject;
public Wrapper(T t) { theObject = t; }
public
<U extends
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
private final T theObject;
public Wrapper(T t) { theObject = t; }
public T getWrapper() { return theObject; }
private final class WrapperComparator
extends Wrapper<? extends Comparable<
WrapperComparator
. In addition, it is also used as part
of the bound of the type parameter
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
void method() {
class Local
<A extends
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
can appear
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 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>();
Although we can refer to the static field through reference variables of
different type, namely of type
SomeClass<String>
SomeClass<Long>
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.
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
private
static
field;
// error
is non-sensical and rightly rejected by the compiler. There is only one
instance of the static field for
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
private final
theObject;
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.
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
private final
theObject;
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
private final
theObject;
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
private final
theObject;