|
Evaluating Software Design Patterns — the "Gang of Four" patterns implemented in Java 6 |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object dk.rode.thesis.meta.reflect.TypeLiteral<T>
T
- The type represented by this type literal.public abstract class TypeLiteral<T>
Represents the type realised as the type parameter T
,
where T
may be a generic type that need not be reifiable.
The type of T
can be retrieved with the getType()
method. It can represent a class, a type variable, a wild-card type,
a component type of a generic type array, or a type parameter of
a parameterised type with a single type parameter (also called a
component type).
The raw type of T
can be retrieved with the
getRawType()
method if T
does not
represent a type variable, a wild-card, or a generic array type
storing type variables.
A type literal can also represent non-reifiable types. Hence, there
can be inconsistencies between T
and the actual type represented
by the literal because of erasure: though T
may seem to
represent a known type in the literal, say Integer
as in
TypeLiteral<Integer>
, the actual type can represent a type
variable, say S
, as is illustrated in the examples below (see
for example literal5
). This is normally not an issue if type
literals are created explicitly and not by generic methods or through
extended inheritance.
Examples:
// Standard creation...
// T = Integer, type = class, raw type = Integer class
TypeLiteral<Integer> literal1 = new TypeLiteral<Integer>(){};
// T = Object[], type = generic array type, raw type = Object class
TypeLiteral<Object[]> literal2 = new TypeLiteral<Object[]>(){};
// T = Class<String>[], type = generic array type, raw type = Class class
TypeLiteral<Class<String>[]> literal3 = new TypeLiteral<Class<String>[]>(){};
// T = List<?>, type = class, raw type = List interface
TypeLiteral<List<?>> literal4 = new TypeLiteral<List<?>>(){};
// Factory creation...
// Generic factory methods...
public static <S> TypeLiteral<S> create1(S value) {
return new TypeLiteral<S>(){};
}
public static <R> TypeLiteral<Comparable<R>> create2(R value) {
return new TypeLiteral<Comparable<R>(){};
}
// Potential trouble: T = Integer, type = type variable (S), raw type = null
TypeLiteral<Integer> literal5 = create1(new Integer(1));
// Potential trouble: T = Class<Integer>, type = type variable (S), raw type = null
TypeLiteral<Class<Integer>> literal6 = create1(Integer.class);
// Potential trouble: T = Class<Integer>, type = type variable (S), raw type = null
TypeLiteral<Class<Integer>> literal7 = create1(null);
// Potential trouble: T = Comparable<Long>,
// type = parameterised type (with type parameter R), raw type = Comparable interface
TypeLiteral<Comparable<Long>> literal8 = create2(Long.class);
// Potential trouble: T = Comparable<Object>,
// type = parameterised type (with type parameter R), raw type = Comparable interface
TypeLiteral<Comparable<Object>> literal9 = create2(null);
// Inheritance...
class Foo extends TypeLiteral<ArrayList<?>>{};
class FooFoo extends TypeLiteral<CharSequence>{};
class Bar extends Foo {};
class Goo<K,V> extends TypeLiteral<Map<K,V>>{};
class FooGoo<K,V> extends TypeLiteral<Map<Long,Void>>{};
class FooBar extends Goo<String,Void> {};
// T = ArrayList<?>, type = parameterised type, raw type = ArrayList class
Foo literal10 = new Foo();
// T = CharSequence, type = class, raw type = CharSequence interface
FooFoo literal11 = new FooFoo();
// Potential trouble: T = Map<K,V>, type = parameterised type, raw type = Map interface
Goo literal12 = new Goo<String,Integer>();
// T = Map<Long,Void>, type = parameterised type, raw type = Map interface
FooGoo literal13 = new FooGoo<String,Integer>();
// Throws illegal argument exception: Bar has no immediate generic super type
Bar literal14 = new Bar();
// Potential trouble: FooBar's immediate generic super type has two type parameters:
// <String,Void>, and so the first, e.g. String
, is used.
FooBar literal15 = new FooBar();
Implementation notes:See [Langer06], for example technical details FAQ106, for an easily understandable discussion on reifiable types and erasure. It contains condensed information from The Java Language Specification, Third Edition [Gosling05] about reifiable types.
getComponentType(Type)
,
getRawType(Type)
,
InstantiableTypeLiteral
Field Summary | |
---|---|
protected Type |
type
The actual Type object representing the
type realised as the type parameter T . |
Constructor Summary | |
---|---|
protected |
TypeLiteral()
Constructor, which creates this type literal to represent the type represented by the type parameter T . |
private |
TypeLiteral(Type type)
Constructor, which creates this type literal to represent the component type of the type supplied as type . |
|
TypeLiteral(TypeLiteral<T> typeLiteral)
Copy constructor, which creates this type literal based on the type represented by typeLiteral . |
Method Summary | ||
---|---|---|
Class<T> |
asClass()
Returns a view of the type represented
by this type literal as a class literal if and only if the
type has a raw type . |
|
Class<T> |
asClass(Class<?> clazz)
Returns a view of the class represented by clazz
as the type represented by this type
literal, if possible. |
|
|
asType(TypeLiteral<S> typeLiteral)
Returns a view of typeLiteral as the type
represented by this type literal, T instead of
S , if possible. |
|
static
|
create(Class<S> clazz)
Returns a type literal representing the generic super-type of class supplied as clazz . |
|
static TypeLiteral<?> |
create(Object object)
Returns a type literal representing the generic super-type of class of object . |
|
static TypeLiteral<?> |
create(Type type)
Returns a type literal representing the component type supplied via type . |
|
boolean |
equals(Object object)
Returns true of object is a type literal
representing the same type
as this type literal, false if not. |
|
static Type |
getComponentType(Type type)
Returns the component type of the type supplied as type if a parameterised type or generic array type,
otherwise type itself. |
|
Class<?> |
getRawType()
Returns the raw type represented by this type literal, if any. |
|
static Class<?> |
getRawType(Type type)
Returns the raw type represented by the type supplied as type , if any. |
|
Type |
getType()
Returns the type represented by this type literal. |
|
int |
hashCode()
Return the hash code of this type literal. |
|
private static boolean |
isAssignableFrom(Type a,
Type b,
boolean equal)
Returns true if a is recursively assignable from
b , false if not. |
|
String |
toString()
Returns the string representation of this type literal. |
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
protected final Type type
Type
object representing the
type realised as the type parameter T
. Never null.
Constructor Detail |
---|
protected TypeLiteral()
T
.
IllegalArgumentException
- If this class is not generic.private TypeLiteral(Type type)
type
.
type
- The type; cannot be null.
NullPointerException
- If type
is null.
IllegalArgumentException
- If type
is a parameterised
type with no type parameter (if more than one, the first
is used). Zero type parameters can occur if type
type
represents a non-parameterised type nested within a parameterised type.getComponentType(Type)
public TypeLiteral(TypeLiteral<T> typeLiteral)
typeLiteral
.
typeLiteral
- The type literal to copy; cannot be null.
NullPointerException
- If typeLiteral
is null.Method Detail |
---|
public Class<T> asClass()
type
represented
by this type literal as a class literal if and only if the
type has a raw type
. Note, that if the type is generic, the returned class literal actually represents the raw type!
asClass(Class)
,
asType(TypeLiteral)
public Class<T> asClass(Class<?> clazz)
clazz
as the type
represented by this type
literal, if possible.
This type must have a raw type
for
this method to have a chance of succeeding.
Note, that if the type is generic, the returned class literal actually represents the raw type!
clazz
- The class to view as the type represented by
this type literal; cannot be null.
NullPointerException
- If clazz
is null.
ClassCastException
- If clazz
cannot be viewed
as the type represented by this type literal.asClass()
,
asType(TypeLiteral)
public <S> TypeLiteral<T> asType(TypeLiteral<S> typeLiteral)
typeLiteral
as the type
represented by this type literal, T
instead of
S
, if possible.
If a cast from S
to T
is not possible,
a class cast exception is thrown. If the type
represented by this type literal does not have a
raw type
, a class cast exception will also
be thrown. Two will card types will cause a class cast exception,
as a simple cast will suffice.
The test for matching types is done recursively, including test for generic array and parameter types with bounded and/or unbounded wild-cards.
S
- The type represented by typeLiteral
.typeLiteral
- The type literal; cannot be null.
typeLiteral
casted to represent T
instead
of S
, if possible; never null.
NullPointerException
- If typeLiteral
is null.
IllegalArgumentException
- If either T
or S
recursively do not represent a parameterised type.
ClassCastException
- If typeLiteral
cannot represent
T
.getComponentType(Type)
,
asClass()
,
asClass(Class)
public static <S> TypeLiteral<?> create(Class<S> clazz)
clazz
.
S
- The type of clazz
.clazz
- The class literal representing the type; cannot be null.
NullPointerException
- If clazz
is null.create(Type)
public static TypeLiteral<?> create(Object object)
object
.
object
- The object to supply the class; cannot be null.
object
; never null.
NullPointerException
- If object
is null.public static TypeLiteral<?> create(Type type)
type
.
type
- The type; cannot be null.
type
;
never null.
NullPointerException
- If type
is null.getComponentType(Type)
,
create(Class)
public boolean equals(Object object)
object
is a type literal
representing the same type
as this type literal, false if not.
equals
in class Object
object
- The object to test; can be null.
public static Type getComponentType(Type type)
type
if a parameterised type or generic array type,
otherwise type
itself. If there are more than one parameter types, the first one is used, and the additional ones ignored.
The component type may be a generic type.
type
- The type to supply the component type, if any;
cannot be null.
NullPointerException
- If type
is null.
IllegalArgumentException
- If type
is a parameterised
type with no type parameters (if more than one, the first
one is used). Zero type parameters can occur if type
type represents a non-parameterised type nested within a
parameterised type.public Class<?> getRawType()
A raw type cannot be returned if this type literal represents a type variable, a wild-card, or a generic array type storing type variables.
The raw type may be the same as getType()
.
getRawType(Type)
public static Class<?> getRawType(Type type)
type
, if any.
A raw type cannot be returned if type
is a type
variable, a wild card, or a generic array type storing
type variables.
type
- The type to use; cannot be null.
NullPointerException
- If type
is null.public Type getType()
getComponentType(Type)
public int hashCode()
hashCode
in class Object
private static final boolean isAssignableFrom(Type a, Type b, boolean equal)
a
is recursively assignable from
b
, false if not.
The test will always returns false if either a
or
b
are a type variable. For generic array and
parameterised types, the test will recurse. Wild cards bounds
are handled as well.
Two unbounded wild card types will return false!
a
- The first type; cannot be null.b
- The second type; cannot be null.equal
- True if a class match is determined using
equals(Object)
instead of
isAssignableFrom(Class)
.
a
is recursively assignable from
b
, false if not.getComponentType(Type)
public String toString()
toString
in class Object
|
Gunni Rode / rode.dk | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |