public Class<S> getType() { return resolveType(type); }
/** * Creates a new {@link TypeDiscoverer} for the given type, type variable map and parent. * * @param type must not be {@literal null}. * @param typeVariableMap must not be {@literal null}. */ protected TypeDiscoverer(Type type, Map<TypeVariable<?>, Type> typeVariableMap) { Assert.notNull(type, "Type must not be null!"); Assert.notNull(typeVariableMap, "TypeVariableMap must not be null!"); this.type = type; this.resolvedType = Lazy.of(() -> resolveType(type)); this.componentType = Lazy.of(this::doGetComponentType); this.valueType = Lazy.of(this::doGetMapValueType); this.typeVariableMap = typeVariableMap; this.hashCode = 17 + (31 * type.hashCode()) + (31 * typeVariableMap.hashCode()); }
/** * Resolves the type variables to be used. Uses the parent's type variable map but overwrites variables locally * declared. * * @param type must not be {@literal null}. * @param parent must not be {@literal null}. * @return will never be {@literal null}. */ private static Map<TypeVariable<?>, Type> calculateTypeVariables(ParameterizedType type, TypeDiscoverer<?> parent) { Class<?> resolvedType = parent.resolveType(type); TypeVariable<?>[] typeParameters = resolvedType.getTypeParameters(); Type[] arguments = type.getActualTypeArguments(); Map<TypeVariable<?>, Type> localTypeVariables = new HashMap<>(parent.getTypeVariableMap()); IntStream.range(0, typeParameters.length) // .mapToObj(it -> Pair.of(typeParameters[it], flattenTypeVariable(arguments[it], localTypeVariables))) // .forEach(it -> localTypeVariables.put(it.getFirst(), it.getSecond())); return localTypeVariables; }
Map<TypeVariable, Type> variableMap = GenericTypeResolver.getTypeVariableMap(resolveType(fieldType));