procyon-reflection framework provides a rich type model inspired by the .NET Framework's
System.Reflection API. All types, including generic type variables and wildcards, are represented by the same
Types from Classes
The most straightforward way to obtain a
Type<T> instance is by calling
clazz is a
Class<T> instance. If the specified class contains generic parameters, then the returned type is the generic type definition (e.g.,
List<E> will be returned if
List.class is specified). The class argument may be a primitive, reference, or array type, and calling
Type.of(String.class) is equivalent to calling
Type.of(String.class).makeArrayType() (see Array Types below).
Primitives and Other Built-In Types
For reduced overhead, type definitions for primitives and common JDK types are exposed via the
Types classes. Any generic type exposed by
Types is always a generic type definition, i.e., all type variables are present and unbound.
There are two ways to obtain an array type definition. The preferred way to resolve
Type<T> for an element type
T is by calling
elementType is a
Type<T>. Alternatively, array types can be obtained directly via
Type.of(T.class). These solutions are equivalent, though
makeArrayType() may perform slightly better.
Parameterized Types (Generic Instance Types)
Given a generic type definition
Type<T>, a generic instance type may be obtained via the
type.MakeGenericType(Type<?>...) method or one of its overloads. The arguments at the call site represent the types to which the target's type variables should be bound. The number of type arguments must exactly match the number of type variables.
For example, given the type
Map<K, V>, the type
Type<Map<String, Integer>> could be obtained as follows:
final Type<Map<String, Integer>> t = Types.Map.makeGenericType(Types.String, Types.Integer);
In the signatures of all members of type
t above, the types
Integer would be substituted for
V in, respectively.
Type class exposes three factory methods for obtaining wildcard types:
makeWildcard()returns an unbounded wildcard (
makeExtendsWildcard(Type<T>)returns a wildcard with an upper bound (
? extends T);
makeSuperWildcard(Type<T>)returns a wildcard with an lower bound (
? super T);
To create a compound type (e.g., the intersection of a base class and one or more interfaces), use one of the
Type.makeCompoundType() methods. You may want to do this to define a complex generic parameter bound.
// Obtain type 'A & B & C' final Type<?> type = Type.makeCompoundType( Type.of(A.class), // super class Type.list(Type.of(B.class), Type.of(C.class)) // super interfaces );
Coming soon (this wiki is a work in progress).