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);