Class TypeUtil

java.lang.Object
name.martingeisse.grumpyjson.util.TypeUtil

public class TypeUtil extends Object
NOT PUBLIC API
  • Method Summary

    Modifier and Type
    Method
    Description
    static Type[]
    expectParameterizedType(Type type, Class<?> expectedRawClass, int expectedNumberOfTypeArguments)
    Like isParameterizedType(), but will fail with a RuntimeException if the type is not as expected, indicating an internal bug in the deserializer because that deserializer should not have been selected for the wrong type in the first place.
    static Type
    expectSingleParameterizedType(Type type, Class<?> expectedRawClass)
    Like isSingleParameterizedType(), but will fail with a RuntimeException if the type is not as expected, indicating an internal bug in the deserializer because that deserializer should not have been selected for the wrong type in the first place.
    static Type[]
    isParameterizedType(Type type, Class<?> expectedRawClass, int expectedNumberOfTypeArguments)
    A common thing to check in deserializers is whether a requested type is a parameterized type with a specific raw type and a specific number of type parameters, but without further restricting the type arguments used for these parameters -- instead, obtaining the type arguments to do something with them.
    static Type
    isSingleParameterizedType(Type type, Class<?> expectedRawClass)
    Like isParameterizedType(), but with expectedNumberOfTypeArguments=1 and returns the single type argument directly, not as an array.
    static Type
    replaceTypeVariables(Type original, Map<String,Type> bindings)
    Returns a type like the original, but with all its type variables replaced by the bound types.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • isParameterizedType

      public static Type[] isParameterizedType(Type type, Class<?> expectedRawClass, int expectedNumberOfTypeArguments)
      A common thing to check in deserializers is whether a requested type is a parameterized type with a specific raw type and a specific number of type parameters, but without further restricting the type arguments used for these parameters -- instead, obtaining the type arguments to do something with them. This method implements this pattern.

      For example, the List<...> deserializer wants to know if the requested type is List<...>, that is, is a parameterized type with the raw class List and exactly one type argument. (Note that a helper method with a simplified return type exists for the special case of one type argument). It would then call this method, and in return get the type arguments which contain the element type of the list.

      Returns null if the type is not as expected.

      Parameters:
      type - the type to check
      expectedRawClass - the expected raw class which the type must use
      expectedNumberOfTypeArguments - the expected number of type arguments
      Returns:
      the type arguments, or null if the type is not as expected
    • isSingleParameterizedType

      public static Type isSingleParameterizedType(Type type, Class<?> expectedRawClass)
      Like isParameterizedType(), but with expectedNumberOfTypeArguments=1 and returns the single type argument directly, not as an array.
      Parameters:
      type - the type to check
      expectedRawClass - the expected raw class which the type must use
      Returns:
      the type argument, or null if the type is not as expected
    • expectParameterizedType

      public static Type[] expectParameterizedType(Type type, Class<?> expectedRawClass, int expectedNumberOfTypeArguments)
      Like isParameterizedType(), but will fail with a RuntimeException if the type is not as expected, indicating an internal bug in the deserializer because that deserializer should not have been selected for the wrong type in the first place.
      Parameters:
      type - the type to check
      expectedRawClass - the expected raw class which the type must use
      expectedNumberOfTypeArguments - the expected number of type arguments
      Returns:
      the type arguments
    • expectSingleParameterizedType

      public static Type expectSingleParameterizedType(Type type, Class<?> expectedRawClass)
      Like isSingleParameterizedType(), but will fail with a RuntimeException if the type is not as expected, indicating an internal bug in the deserializer because that deserializer should not have been selected for the wrong type in the first place.
      Parameters:
      type - the type to check
      expectedRawClass - the expected raw class which the type must use
      Returns:
      the type argument
    • replaceTypeVariables

      public static Type replaceTypeVariables(Type original, Map<String,Type> bindings)
      Returns a type like the original, but with all its type variables replaced by the bound types. This method expects to get bindings for all type variables, and will throw an exception if it encounters a type variable for which no binding was passed (simply to fail fast -- this method itself could leave unbound type variables in the result, but is not expected to be used that way).

      This method does not check if the types from the bindings contain variables, and if they do, these variables will be part of the result. However, this method is not expected to be used that way, reflecting how type parameters get bound: For a generic type MyType<A,B>, you cannot build a parameterized version of that type like MyType<String,List<A>> -- that is, the binding for type parameter B cannot use the type variable A to define its bound type. This is a bit confusing to explain because such a binding can absolutely use a type variable A which is bound in its outer context, but that is a different A than the type variable to replace. Also, the way we bind type variables, such outer type variables should have been replaced already before calling this function.

      This method can only handle three kinds of types, raw class objects, ParameterizedType and, of course, type variables. Any other type will cause an exception. The reason is that these cases are not needed by grumpyjson because they cause other problems downstream -- fields using such types cannot be converted from JSON because the type information is not sufficient. However, they can occur due to user error and therefore should produce a clean error message.

      Parameters:
      original - the original type to replace type variables in
      bindings - the bindings of variables to types
      Returns:
      the type with type variables replaced