@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(
              
              toGenericType(cls.getComponentType()).runtimeType);
      @SuppressWarnings("unchecked") 
      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") 
      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.
Returns the type token representing the generic type declaration of { @code cls } . For example : { @code TypeToken . getGenericType ( Iterable . class ) } returns { @code Iterable<T > } .