guava/src/com/google/common/reflect/TypeToken.java
final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
    if (runtimeType instanceof TypeVariable) {
      return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
    }
    if (runtimeType instanceof WildcardType) {
      return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
    }
    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
    for (Type interfaceType : getRawType().getGenericInterfaces()) {
      @SuppressWarnings("unchecked") // interface of T
      TypeToken<? super T> resolvedInterface =
          (TypeToken<? super T>) resolveSupertype(interfaceType);
      builder.add(resolvedInterface);
    }
    return builder.build();
  }
final ImmutableList<TypeToken<? super T>> getGenericInterfaces() {
    if (runtimeType instanceof TypeVariable) {
      return boundsAsInterfaces(((TypeVariable<?>) runtimeType).getBounds());
    }
    if (runtimeType instanceof WildcardType) {
      return boundsAsInterfaces(((WildcardType) runtimeType).getUpperBounds());
    }
    ImmutableList.Builder<TypeToken<? super T>> builder = ImmutableList.builder();
    for (Type interfaceType : getRawType().getGenericInterfaces()) {
      @SuppressWarnings("unchecked") // interface of T
      TypeToken<? super T> resolvedInterface =
          (TypeToken<? super T>) resolveSupertype(interfaceType);
      builder.add(resolvedInterface);
    }
    return builder.build();
  }
Returns the generic interfaces that this type directly {@code implements}. This method is
similar but different from {@link Class#getGenericInterfaces()}. For example, {@code new
TypeToken<List<String>>() {}.getGenericInterfaces()} will return a list that contains {@code
new TypeToken<Iterable<String>>() {}}; while {@code List.class.getGenericInterfaces()} will
return an array that contains {@code Iterable<T>}, where the {@code T} is the type variable
declared by interface {@code Iterable}.

<p>If this type is a type variable or wildcard, its upper bounds are examined and those that
are either an interface or upper-bounded only by interfaces are returned. This means that the
returned types could include type variables too.