guava/src/com/google/common/reflect/TypeToken.java
@VisibleForTesting
  static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
    if (cls.isArray()) {
      Type arrayOfGenericType =
          Types.newArrayType(
              // If we are passed with int[].class, don't turn it to GenericArrayType
              toGenericType(cls.getComponentType()).runtimeType);
      @SuppressWarnings("unchecked") // array is covariant
      TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
      return result;
    }
    TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
    Type ownerType =
        cls.isMemberClass() && !Modifier.isStatic(cls.getModifiers())
            ? toGenericType(cls.getEnclosingClass()).runtimeType
            : null;

    if ((typeParams.length > 0) || ((ownerType != null) && ownerType != cls.getEnclosingClass())) {
      @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
      TypeToken<? extends T> type =
          (TypeToken<? extends T>)
              of(Types.newParameterizedTypeWithOwner(ownerType, cls, typeParams));
      return type;
    } else {
      return of(cls);
    }
  }
@VisibleForTesting
  static <T> TypeToken<? extends T> toGenericType(Class<T> cls) {
    if (cls.isArray()) {
      Type arrayOfGenericType =
          Types.newArrayType(
              // If we are passed with int[].class, don't turn it to GenericArrayType
              toGenericType(cls.getComponentType()).runtimeType);
      @SuppressWarnings("unchecked") // array is covariant
      TypeToken<? extends T> result = (TypeToken<? extends T>) of(arrayOfGenericType);
      return result;
    }
    TypeVariable<Class<T>>[] typeParams = cls.getTypeParameters();
    Type ownerType =
        cls.isMemberClass() && !Modifier.isStatic(cls.getModifiers())
            ? toGenericType(cls.getEnclosingClass()).runtimeType
            : null;

    if ((typeParams.length > 0) || ((ownerType != null) && ownerType != cls.getEnclosingClass())) {
      @SuppressWarnings("unchecked") // Like, it's Iterable<T> for Iterable.class
      TypeToken<? extends T> type =
          (TypeToken<? extends T>)
              of(Types.newParameterizedTypeWithOwner(ownerType, cls, typeParams));
      return type;
    } else {
      return of(cls);
    }
  }
Returns the type token representing the generic type declaration of {@code cls}. For example:
{@code TypeToken.getGenericType(Iterable.class)} returns {@code Iterable<T>}.

<p>If {@code cls} isn't parameterized and isn't a generic array, the type token of the class is
returned.