Example usage for java.lang Class isPrimitive

List of usage examples for java.lang Class isPrimitive

Introduction

In this page you can find the example usage for java.lang Class isPrimitive.

Prototype

@HotSpotIntrinsicCandidate
public native boolean isPrimitive();

Source Link

Document

Determines if the specified Class object represents a primitive type.

Usage

From source file:ca.oson.json.Oson.java

private <E> String array2Json(FieldData objectDTO) {
    Object value = objectDTO.valueToProcess;
    Class<?> returnType = objectDTO.returnType;

    int size = 0;
    if (value != null && (size = Array.getLength(value)) > 0) {
        Function function = objectDTO.getSerializer();
        String valueToReturn = null;

        if (function != null) {
            try {

                // suppose to return String, but in case not, try to process
                if (function instanceof DataMapper2JsonFunction) {
                    DataMapper classData = new DataMapper(returnType, value, objectDTO.classMapper,
                            objectDTO.level, getPrettyIndentation());
                    return ((DataMapper2JsonFunction) function).apply(classData);

                } else if (function instanceof Array2JsonFunction) {
                    return ((Array2JsonFunction) function).apply((E[]) value);

                } else {

                    Object returnedValue = null;
                    if (function instanceof FieldData2JsonFunction) {
                        FieldData2JsonFunction f = (FieldData2JsonFunction) function;
                        FieldData fieldData = objectDTO.clone();
                        returnedValue = f.apply(fieldData);
                    } else {
                        returnedValue = function.apply(value);
                    }//from  w w w  .  j  a v  a2  s.  c  o  m

                    if (returnedValue instanceof Optional) {
                        returnedValue = ObjectUtil.unwrap(returnedValue);
                    }

                    if (returnedValue == null) {
                        return null;

                    } else if (Array.class.isAssignableFrom(returnedValue.getClass())) {
                        // keep on processing
                        value = returnedValue;
                        size = Array.getLength(value);

                    } else {
                        objectDTO.valueToProcess = returnedValue;
                        return object2String(objectDTO);
                    }
                }

            } catch (Exception ex) {
            }
        }

        String repeated = getPrettyIndentationln(objectDTO.level);
        objectDTO.incrLevel();
        String repeatedItem = getPrettyIndentationln(objectDTO.level);
        Class ctype = objectDTO.getComponentType(getJsonClassType());

        List<String> list = new ArrayList<>();

        for (int i = 0; i < size; i++) {
            Object componentValue = Array.get(value, i);
            String str = null;
            if (componentValue != null) {
                FieldData newFieldData = new FieldData(componentValue, componentValue.getClass(),
                        objectDTO.json2Java, objectDTO.level, objectDTO.set);
                newFieldData.returnType = guessComponentType(newFieldData);
                newFieldData.fieldMapper = objectDTO.fieldMapper;
                str = object2Json(newFieldData);
            }

            if (str == null
                    && ((ctype != null && ctype.isPrimitive()) || getDefaultType() == JSON_INCLUDE.DEFAULT)) {
                str = getDefaultValue(ctype).toString();
            }

            list.add(str);
        }

        if (objectDTO.classMapper.orderArrayAndList) {
            Collections.sort(list);
        }

        StringBuilder sbuilder = new StringBuilder();
        for (String str : list) {
            sbuilder.append(repeatedItem + str + ",");
        }

        String str = sbuilder.toString();
        size = str.length();
        if (size > 0) {
            return "[" + str.substring(0, size - 1) + repeated + "]";
        }
    }

    return array2JsonDefault(objectDTO);
}

From source file:ca.oson.json.Oson.java

@SuppressWarnings("unchecked")
private <E> E json2Object(FieldData objectDTO) {
    // String value, Class<E> returnType
    Class<E> returnType = objectDTO.returnType;

    Object value = objectDTO.valueToProcess;
    if (StringUtil.isNull(value)) {
        if (objectDTO.required()) {
            return (E) DefaultValue.getSystemDefault(returnType);
        }// w w  w.jav a  2  s .c  om

        return null;
    }

    if (returnType == null || returnType == Object.class) {
        if (StringUtil.isEmpty(value)) {
            return null;
        }

        returnType = (Class<E>) value.getClass();
        objectDTO.returnType = returnType;
    }

    // first, get the class mapper
    //if (objectDTO.fieldMapper == null && objectDTO.classMapper == null) {
    objectDTO.classMapper = getGlobalizedClassMapper(returnType);
    //}

    if (returnType == String.class) {
        return (E) json2String(objectDTO);

        //      } else if (returnType == Optional.class) {
        //         return (E) json2Optional(objectDTO);

    } else if (returnType == Character.class || returnType == char.class) {
        return (E) json2Character(objectDTO);

    } else if (returnType == Boolean.class || returnType == boolean.class
            || returnType == AtomicBoolean.class) {
        return (E) json2Boolean(objectDTO);

    } else if (Number.class.isAssignableFrom(returnType) || returnType.isPrimitive()) {

        objectDTO.valueToProcess = StringUtil.unquote(objectDTO.valueToProcess, isEscapeHtml());

        if (returnType == Integer.class || returnType == int.class) {
            return (E) json2Integer(objectDTO);
        } else if (returnType == Long.class || returnType == long.class) {
            return (E) json2Long(objectDTO);

        } else if (returnType == Double.class || returnType == double.class) {
            return (E) json2Double(objectDTO);

        } else if (returnType == Byte.class || returnType == byte.class) {
            return (E) json2Byte(objectDTO);

        } else if (returnType == Short.class || returnType == short.class) {
            return (E) json2Short(objectDTO);

        } else if (returnType == Float.class || returnType == float.class) {
            return (E) json2Float(objectDTO);

        } else if (returnType == BigDecimal.class) {
            return (E) json2BigDecimal(objectDTO);

        } else if (returnType == BigInteger.class) {
            return (E) json2BigInteger(objectDTO);

        } else if (returnType == AtomicInteger.class) {
            return (E) json2AtomicInteger(objectDTO);

        } else if (returnType == AtomicLong.class) {
            return (E) json2AtomicLong(objectDTO);

        } else { // default to Double, in case no specific type is specified
            return (E) json2Double(objectDTO);
        }

    } else if (returnType.isEnum() || Enum.class.isAssignableFrom(returnType)) {
        return (E) json2Enum(objectDTO);

    } else if (returnType == Date.class || Date.class.isAssignableFrom(returnType)) {
        return (E) json2Date(objectDTO);

    } else if (returnType.isArray() || Collection.class.isAssignableFrom(returnType)) {

        Collection<E> values = null;
        Class<?> valueType = value.getClass();
        if (Collection.class.isAssignableFrom(valueType)) {
            values = (Collection<E>) value;
        } else if (valueType.isArray()) {
            values = Arrays.asList((E[]) value);
        }

        if (values == null) {
            //return null;
        } else {
            objectDTO.valueToProcess = values;
        }

        Class<E> componentType = (Class<E>) returnType.getComponentType();
        if (componentType == null) {
            objectDTO.incrLevel();
            componentType = guessComponentType(objectDTO);
            objectDTO.descLevel();
        }
        if (componentType == null) {
            componentType = CollectionArrayTypeGuesser.guessElementType(values, returnType, getJsonClassType());
        }
        if (componentType == null)
            componentType = (Class<E>) Object.class;

        if (componentType.isPrimitive()) {
            E arr = null;
            if (componentType == int.class) {
                arr = (E) json2ArrayInt(objectDTO);

            } else if (componentType == byte.class) {
                arr = (E) json2ArrayByte(objectDTO);
            } else if (componentType == char.class) {
                arr = (E) json2ArrayChar(objectDTO);
            } else if (componentType == float.class) {
                arr = (E) json2ArrayFloat(objectDTO);
            } else if (componentType == double.class) {
                arr = (E) json2ArrayDouble(objectDTO);
            } else if (componentType == long.class) {
                arr = (E) json2ArrayLong(objectDTO);
            } else if (componentType == short.class) {
                arr = (E) json2ArrayShort(objectDTO);
            } else if (componentType == boolean.class) {
                arr = (E) json2ArrayBoolean(objectDTO);
            } else {
                // return null;
            }

            if (arr != null && objectDTO.classMapper.orderArrayAndList) {
                Arrays.sort((E[]) arr);
            }

            return arr;

        } else if (Collection.class.isAssignableFrom(returnType)) {
            return (E) json2Collection(objectDTO);

        } else {
            return (E) json2Array(objectDTO);
        }

    } else if (returnType != Optional.class && Map.class.isAssignableFrom(returnType)) {
        return (E) json2Map(objectDTO);

    } else {
        if (objectDTO.returnObj == null) {
            return (E) deserialize2Object(value, returnType, objectDTO);

        } else {
            objectDTO.returnType = returnType;
            return (E) deserialize2Object(objectDTO);
        }
    }
}

From source file:ca.oson.json.Oson.java

private <E, R> String object2Json(FieldData objectDTO) {
    E value = (E) objectDTO.valueToProcess;

    Class<R> returnType = objectDTO.returnType;

    if (returnType == null || returnType == Object.class) {
        if (value != null) {
            returnType = (Class<R>) value.getClass();
            objectDTO.returnType = returnType;
        }//from   w w  w.  j  a  v  a2s .co m
    }

    int level = objectDTO.level;
    //      if (value == null) {
    //         if ((returnType != null && returnType.isPrimitive())  || objectDTO.required()) {
    //            Object obj = DefaultValue.getSystemDefault(returnType);
    //            if (obj != null) {
    //               return obj.toString();
    //            }
    //
    //         }
    //
    //         return processNullValue(level);
    //      }

    // first, get the class mapper
    //if (objectDTO.mapper == null && objectDTO.classMapper == null) {
    objectDTO.classMapper = getGlobalizedClassMapper(returnType);
    //}

    if (objectDTO.defaultType == null) {
        objectDTO.defaultType = getDefaultType();
    }

    if (returnType == null) {
        if (value == null) {
            return processNullValue(level);
        } else if (objectDTO.isJsonRawValue()) {
            return value.toString();
        } else {
            return StringUtil.doublequote(value, isEscapeHtml());
        }

    } else if (value instanceof Optional) {
        return optional2Json(objectDTO);

    } else if (returnType == String.class) {
        value = (E) string2Json(objectDTO);

        if (value == null) {
            return processNullValue(level);
        }

        String str = value.toString();

        if (objectDTO.isJsonRawValue()) {
            return str;
        } else {
            if (isMapListArrayObject(str)) {
                return str;

            } else {
                return StringUtil.doublequote(str, isEscapeHtml());
            }
        }

    } else if (Character.class.isAssignableFrom(returnType) || char.class.isAssignableFrom(returnType)) {
        String valueToReturn = character2Json(objectDTO);

        if (valueToReturn == null) {
            return processNullValue(level);
        }

        if (objectDTO.isJsonRawValue()) {
            return (String) valueToReturn;
        } else {
            return StringUtil.doublequote(valueToReturn, isEscapeHtml());
        }

    } else if (BooleanUtil.isBoolean(returnType)
            && (value == null || BooleanUtil.isBoolean(value.getClass()))) {
        String returnedValue = boolean2Json(objectDTO);

        if (returnedValue != null) {
            if (objectDTO.isJsonRawValue()) {
                return returnedValue;

            } else if ("true".equalsIgnoreCase(returnedValue)) {
                return "true";

            } else if ("false".equalsIgnoreCase(returnedValue)) {
                return "false";

            } else if (StringUtil.isNumeric(returnedValue)) {
                return returnedValue;

            } else {
                return StringUtil.doublequote(returnedValue, isEscapeHtml());
            }
        }

        return processNullValue(level);

    } else if (Number.class.isAssignableFrom(returnType) || returnType.isPrimitive()) {

        if (returnType == Number.class && value != null) {
            returnType = (Class<R>) value.getClass();
            objectDTO.returnType = returnType;
        }

        String returnedValue = null;

        if (returnType == Integer.class || returnType == int.class) {
            returnedValue = integer2Json(objectDTO);

        } else if (returnType == Long.class || returnType == long.class) {
            returnedValue = long2Json(objectDTO);

        } else if (returnType == Byte.class || returnType == byte.class) {
            returnedValue = byte2Json(objectDTO);

        } else if (returnType == Double.class || returnType == double.class) {
            returnedValue = double2Json(objectDTO);

        } else if (returnType == Short.class || returnType == short.class) {
            returnedValue = short2Json(objectDTO);

        } else if (returnType == Float.class || returnType == float.class) {
            returnedValue = float2Json(objectDTO);

        } else if (returnType == BigDecimal.class) {
            returnedValue = bigDecimal2Json(objectDTO);

        } else if (returnType == BigInteger.class) {
            returnedValue = bigInteger2Json(objectDTO);

        } else if (returnType == AtomicInteger.class) {
            returnedValue = atomicInteger2Json(objectDTO);

        } else if (returnType == AtomicLong.class) {
            returnedValue = atomicLong2Json(objectDTO);

        } else if (value != null) {
            returnedValue = double2Json(objectDTO);

        } else {
            return processNullValue(level);
        }

        if (returnedValue != null) {
            if (objectDTO.isJsonRawValue()) {
                return returnedValue;

            } else if (StringUtil.isNumeric(returnedValue)) {
                return returnedValue;

            } else {
                return StringUtil.doublequote(returnedValue, isEscapeHtml());
            }
        }

        return processNullValue(level);

    } else if (Date.class.isAssignableFrom(returnType)) {
        String returnedValue = date2Json(objectDTO);

        if (returnedValue != null) {
            if (objectDTO.isJsonRawValue()) {
                return returnedValue;

            } else if (StringUtil.isNumeric(returnedValue)) {
                return returnedValue;

            } else {
                return StringUtil.doublequote(returnedValue, isEscapeHtml());
            }
        }

        return processNullValue(level);

        // returnType.isEnum()  || value instanceof Enum<?>
    } else if (Enum.class.isAssignableFrom(returnType)) {

        String returnedValue = enum2Json(objectDTO);

        if (returnedValue != null) {
            if (objectDTO.isJsonRawValue()) {
                return returnedValue;

            } else if (StringUtil.isNumeric(returnedValue)) {
                return returnedValue;

            } else {
                return StringUtil.doublequote(returnedValue, isEscapeHtml());
            }
        }

        return processNullValue(level);

    } else if (Collection.class.isAssignableFrom(returnType)) {
        return collection2Json(objectDTO);

    } else if (returnType.isArray()) {
        return array2Json(objectDTO);

    } else if (Map.class.isAssignableFrom(returnType)) {
        return map2Json(objectDTO);

    } else if (objectDTO.level < getLevel()) {
        if (value == null) {
            return null;
        }

        return object2Serialize(objectDTO);

    } else {
        return "{}";
    }
}

From source file:com.clark.func.Functions.java

/**
 * Get the number of steps required to promote a primitive number to another
 * type.//from w  w w.j a v  a 2s. c  o  m
 * 
 * @param srcClass
 *            the (primitive) source class
 * @param destClass
 *            the (primitive) destination class
 * @return The cost of promoting the primitive
 */
private static float getPrimitivePromotionCost(final Class<?> srcClass, final Class<?> destClass) {
    float cost = 0.0f;
    Class<?> cls = srcClass;
    if (!cls.isPrimitive()) {
        // slight unwrapping penalty
        cost += 0.1f;
        cls = wrapperToPrimitive(cls);
    }
    for (int i = 0; cls != destClass && i < ORDERED_PRIMITIVE_TYPES.length; i++) {
        if (cls == ORDERED_PRIMITIVE_TYPES[i]) {
            cost += 0.1f;
            if (i < ORDERED_PRIMITIVE_TYPES.length - 1) {
                cls = ORDERED_PRIMITIVE_TYPES[i + 1];
            }
        }
    }
    return cost;
}

From source file:com.clark.func.Functions.java

/**
 * Gets the number of steps required needed to turn the source class into
 * the destination class. This represents the number of steps in the object
 * hierarchy graph.//  ww w.java 2  s . c  o  m
 * 
 * @param srcClass
 *            The source class
 * @param destClass
 *            The destination class
 * @return The cost of transforming an object
 */
private static float getObjectTransformationCost(Class<?> srcClass, Class<?> destClass) {
    if (destClass.isPrimitive()) {
        return getPrimitivePromotionCost(srcClass, destClass);
    }
    float cost = 0.0f;
    while (destClass != null && !destClass.equals(srcClass)) {
        if (destClass.isInterface() && isAssignable(srcClass, destClass)) {
            // slight penalty for interface match.
            // we still want an exact match to override an interface match,
            // but
            // an interface match should override anything where we have to
            // get a superclass.
            cost += 0.25f;
            break;
        }
        cost++;
        destClass = destClass.getSuperclass();
    }
    /*
     * If the destination class is null, we've travelled all the way up to
     * an Object match. We'll penalize this by adding 1.5 to the cost.
     */
    if (destClass == null) {
        cost += 1.5f;
    }
    return cost;
}

From source file:com.clark.func.Functions.java

/**
 * Clone an object.//from   ww w .  j a v a2 s. c  o  m
 * 
 * @param <T>
 *            the type of the object
 * @param o
 *            the object to clone
 * @return the clone if the object implements {@link Cloneable} otherwise
 *         <code>null</code>
 * @throws CloneFailedException
 *             if the object is cloneable and the clone operation fails
 * @since 3.0
 */
public static <T> T objectClone(final T o) {
    if (o instanceof Cloneable) {
        final Object result;
        if (o.getClass().isArray()) {
            final Class<?> componentType = o.getClass().getComponentType();
            if (!componentType.isPrimitive()) {
                result = ((Object[]) o).clone();
            } else {
                int length = Array.getLength(o);
                result = Array.newInstance(componentType, length);
                while (length-- > 0) {
                    Array.set(result, length, Array.get(o, length));
                }
            }
        } else {
            try {
                final Method clone = o.getClass().getMethod("clone");
                result = clone.invoke(o);
            } catch (final NoSuchMethodException e) {
                throw new CloneFailedException(
                        "Cloneable type " + o.getClass().getName() + " has no clone method", e);
            } catch (final IllegalAccessException e) {
                throw new CloneFailedException("Cannot clone Cloneable type " + o.getClass().getName(), e);
            } catch (final InvocationTargetException e) {
                throw new CloneFailedException("Exception cloning Cloneable type " + o.getClass().getName(),
                        e.getCause());
            }
        }
        @SuppressWarnings("unchecked")
        final T checked = (T) result;
        return checked;
    }

    return null;
}

From source file:com.clark.func.Functions.java

/**
 * <p>//from  w  w w . j a v  a 2s .co  m
 * Checks if the subject type may be implicitly cast to the target class
 * following the Java generics rules.
 * </p>
 * 
 * @param type
 *            the subject type to be assigned to the target type
 * @param toClass
 *            the target class
 * @return true if <code>type</code> is assignable to <code>toClass</code>.
 */
private static boolean isAssignable(Type type, Class<?> toClass) {
    if (type == null) {
        // consistency with ClassUtils.isAssignable() behavior
        return toClass == null || !toClass.isPrimitive();
    }

    // only a null type can be assigned to null type which
    // would have cause the previous to return true
    if (toClass == null) {
        return false;
    }

    // all types are assignable to themselves
    if (toClass.equals(type)) {
        return true;
    }

    if (type instanceof Class<?>) {
        // just comparing two classes
        return isAssignable((Class<?>) type, toClass);
    }

    if (type instanceof ParameterizedType) {
        // only have to compare the raw type to the class
        return isAssignable(getRawType((ParameterizedType) type), toClass);
    }

    // *
    if (type instanceof TypeVariable<?>) {
        // if any of the bounds are assignable to the class, then the
        // type is assignable to the class.
        for (Type bound : ((TypeVariable<?>) type).getBounds()) {
            if (isAssignable(bound, toClass)) {
                return true;
            }
        }

        return false;
    }

    // the only classes to which a generic array type can be assigned
    // are class Object and array classes
    if (type instanceof GenericArrayType) {
        return toClass.equals(Object.class)
                || toClass.isArray() && isAssignable(((GenericArrayType) type).getGenericComponentType(),
                        toClass.getComponentType());
    }

    // wildcard types are not assignable to a class (though one would think
    // "? super Object" would be assignable to Object)
    if (type instanceof WildcardType) {
        return false;
    }

    throw new IllegalStateException("found an unhandled type: " + type);
}

From source file:com.clark.func.Functions.java

/**
 * <p>//from ww  w . ja va2  s.  com
 * Checks if one <code>Class</code> can be assigned to a variable of another
 * <code>Class</code>.
 * </p>
 * 
 * <p>
 * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this
 * method takes into account widenings of primitive classes and
 * <code>null</code>s.
 * </p>
 * 
 * <p>
 * Primitive widenings allow an int to be assigned to a long, float or
 * double. This method returns the correct result for these cases.
 * </p>
 * 
 * <p>
 * <code>Null</code> may be assigned to any reference type. This method will
 * return <code>true</code> if <code>null</code> is passed in and the
 * toClass is non-primitive.
 * </p>
 * 
 * <p>
 * Specifically, this method tests whether the type represented by the
 * specified <code>Class</code> parameter can be converted to the type
 * represented by this <code>Class</code> object via an identity conversion
 * widening primitive or widening reference conversion. See
 * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language Specification</a></em>
 * , sections 5.1.1, 5.1.2 and 5.1.4 for details.
 * </p>
 * 
 * @param cls
 *            the Class to check, may be null
 * @param toClass
 *            the Class to try to assign into, returns false if null
 * @param autoboxing
 *            whether to use implicit autoboxing/unboxing between primitives
 *            and wrappers
 * @return <code>true</code> if assignment possible
 */
public static boolean isAssignable(Class<?> cls, Class<?> toClass, boolean autoboxing) {
    if (toClass == null) {
        return false;
    }
    // have to check for null, as isAssignableFrom doesn't
    if (cls == null) {
        return !(toClass.isPrimitive());
    }
    // autoboxing:
    if (autoboxing) {
        if (cls.isPrimitive() && !toClass.isPrimitive()) {
            cls = primitiveToWrapper(cls);
            if (cls == null) {
                return false;
            }
        }
        if (toClass.isPrimitive() && !cls.isPrimitive()) {
            cls = wrapperToPrimitive(cls);
            if (cls == null) {
                return false;
            }
        }
    }
    if (cls.equals(toClass)) {
        return true;
    }
    if (cls.isPrimitive()) {
        if (toClass.isPrimitive() == false) {
            return false;
        }
        if (Integer.TYPE.equals(cls)) {
            return Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass);
        }
        if (Long.TYPE.equals(cls)) {
            return Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass);
        }
        if (Boolean.TYPE.equals(cls)) {
            return false;
        }
        if (Double.TYPE.equals(cls)) {
            return false;
        }
        if (Float.TYPE.equals(cls)) {
            return Double.TYPE.equals(toClass);
        }
        if (Character.TYPE.equals(cls)) {
            return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass)
                    || Double.TYPE.equals(toClass);
        }
        if (Short.TYPE.equals(cls)) {
            return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass)
                    || Double.TYPE.equals(toClass);
        }
        if (Byte.TYPE.equals(cls)) {
            return Short.TYPE.equals(toClass) || Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass)
                    || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass);
        }
        // should never get here
        return false;
    }
    return toClass.isAssignableFrom(cls);
}

From source file:com.clark.func.Functions.java

/**
 * <p>//from   w w  w  .j a  v a 2  s  . c  o m
 * </p>
 * 
 * @param cls
 * @param toClass
 * @param subtypeVarAssigns
 * @return
 */
private static Map<TypeVariable<?>, Type> getTypeArguments(Class<?> cls, Class<?> toClass,
        Map<TypeVariable<?>, Type> subtypeVarAssigns) {
    // make sure they're assignable
    if (!isAssignable(cls, toClass)) {
        return null;
    }

    // can't work with primitives
    if (cls.isPrimitive()) {
        // both classes are primitives?
        if (toClass.isPrimitive()) {
            // dealing with widening here. No type arguments to be
            // harvested with these two types.
            return new HashMap<TypeVariable<?>, Type>();
        }

        // work with wrapper the wrapper class instead of the primitive
        cls = primitiveToWrapper(cls);
    }

    // create a copy of the incoming map, or an empty one if it's null
    HashMap<TypeVariable<?>, Type> typeVarAssigns = subtypeVarAssigns == null
            ? new HashMap<TypeVariable<?>, Type>()
            : new HashMap<TypeVariable<?>, Type>(subtypeVarAssigns);

    // no arguments for the parameters, or target class has been reached
    if (cls.getTypeParameters().length > 0 || toClass.equals(cls)) {
        return typeVarAssigns;
    }

    // walk the inheritance hierarchy until the target class is reached
    return getTypeArguments(getClosestParentType(cls, toClass), toClass, typeVarAssigns);
}