Skeletal implementation of interface
javax.lang.model.util.Types,
plus concrete realization backed by core Java Reflection API, akin to
JDK Enhancement Proposal (JEP) 119
- source compatible with Java 7 and 8
- algorithms, relations, and properties of Java Language Specification
implemented exclusively in terms of
javax.lang.modelinterfaces; therefore supports different concrete implementations ofjavax.lang.modelinterfaces - besides the generic skeletal implementation of
javax.lang.model.util.Types, also includes a concrete implementation backed by the Java Reflection API - implemented in plain Java with no dependencies; easily embeddable in projects that have Java types as part of their domain model (for instance, domain-specific languages on top of the JVM that need some sort of support for Java generic types)
- contract tests for the methods and classes that clients of the library need
to provide in order to support other implementations of
javax.lang.modelinterfaces - tests have virtually full code coverage
- contains a complete implementation of
javax.lang.model.util.Typesmethods pertaining to JLS §4 (including primitive types, reference types, type variables, parameterized types, type erasure, raw types, intersection types, and subtyping) and §5.1.10 (capture conversion) - also includes method for resolving formal type parameters to actual type
arguments (for example, determining the actual type argument to
Comparable<T>, given typeInteger) - methods pertaining to non-type elements (notably,
ExecutableElementandVariableElement) not currently implemented - Code makes use of JSR 305 annotations (e.g.,
@Nullable)
Revised BSD (3-Clause) License
Published releases (compiled for Java 7 and up) are available on Maven Central.
<dependency>
<groupId>net.florianschoppmann.java</groupId>
<artifactId>java-types</artifactId>
<version>1.0.1</version>
</dependency>
The following examples show some use cases of class ReflectionTypes, the Java
Reflection API-based implementation of javax.lang.model.util.Types provided
by this project. While the bulk of the functionality of ReflectionTypes is
provided by an abstract, skeletal-implementation class called AbstractTypes,
class ReflectionTypes provides methods typeElement() and typeMirror()
that facilitate converting Java classes and generic types to TypeElement and
TypeMirror instances.
(see JLS §4.10 and its references)
ReflectionTypes types = ReflectionTypes.getInstance();
// listSuperNumberType: List<? super Number>
DeclaredType listSuperNumberType = types.getDeclaredType(
types.typeElement(List.class),
types.getWildcardType(null, types.typeMirror(Number.class))
);
// iterableExtendsNumberType: Iterable<? extends Number>
DeclaredType iterableExtendsNumberType = types.getDeclaredType(
types.typeElement(Iterable.class),
types.getWildcardType(types.typeMirror(Number.class), null)
);
// iterableType: Iterable<?>
DeclaredType iterableType = types.getDeclaredType(
types.typeElement(Iterable.class),
types.getWildcardType(null, null)
);
assert types.isSubtype(listSuperNumberType, iterableType);
assert types.isSubtype(iterableExtendsNumberType, iterableType);
assert !types.isSubtype(listSuperNumberType, iterableExtendsNumberType);(see JLS §4.5, §8.1, and their references)
ReflectionTypes types = ReflectionTypes.getInstance();
// actual type arguments to Comparable, given the (raw) subtype ScheduledFuture
List<? extends TypeMirror> typeArguments = types.resolveActualTypeArguments(
types.typeElement(Comparable.class),
types.typeMirror(ScheduledFuture.class)
);
assert typeArguments.equals(
Collections.singletonList(types.typeMirror(Delayed.class))
);(taken from Example 8.1.2-1 of JLS 8, see also JLS §5.1.10 and its references)
// The following are top-level definitions
interface ConvertibleTo<T> {
T convert();
}
class ReprChange<T extends ConvertibleTo<S>,
S extends ConvertibleTo<T>> {
T t;
void set(S s) { t = s.convert(); }
S get() { return t.convert(); }
}
class Amount implements ConvertibleTo<Integer> {
@Override public Integer convert() { return 42; }
}
// [...]
ReflectionTypes types = ReflectionTypes.getInstance();
// reprChangeType: ReprChange<Amount, ?>
DeclaredType reprChangeType = types.getDeclaredType(
types.typeElement(ReprChange.class),
types.typeMirror(Amount.class),
types.getWildcardType(null, null)
);
TypeMirror convertedType = types.capture(reprChangeType);
TypeVariable capturedS
= (TypeVariable) ((DeclaredType) convertedType).getTypeArguments().get(1);
// convertibleToAmountType: ConvertibleTo<Amount>
DeclaredType convertibleToAmountType = types.getDeclaredType(
types.typeElement(ConvertibleTo.class),
types.typeMirror(Amount.class)
);
assert capturedS.getUpperBound().equals(convertibleToAmountType);