code: public static Class<?> genericTypeOf(Class<?> rootClass, Class<?> targetBaseClass, Class<?> targetBaseInterface) {
          //looking for candidates in the hierarchy of rootClass
          Class<?> match = rootClass;
          while(match != Object.class) {
              //check the super class first
              if (match.getSuperclass() == targetBaseClass) {
                  return extractGeneric(match.getGenericSuperclass());
              }
              //check the interfaces (recursively)
              Type genericInterface = findGenericInterface(match, targetBaseInterface);
              if (genericInterface != null) {
                  return extractGeneric(genericInterface);
              }
              //recurse the hierarchy
              match = match.getSuperclass();
          }
          return Object.class;
      }
docs: Extract generic type of root class either from the target base class or from target base interface.
  Examples:
  <p>
  1. Foo implements IFoo[Integer]:
  genericTypeOf(Foo.class, Object.class, IFoo.class) returns Integer
  <p>
  2. Foo extends BaseFoo[String]:
  genericTypeOf(Foo.class, BaseFoo.class, IFoo.class) returns String
  <p>
  3. Foo extends BaseFoo; BaseFoo implements IFoo[String]:
  genericTypeOf(Foo.class, BaseFoo.class, Object.class) returns String
  <p>
  Does not support nested generics, only supports single type parameter.
  
  @param rootClass - the root class that the search begins from
  @param targetBaseClass - if one of the classes in the root class' hierarchy extends this base class
  it will be used for generic type extraction
  @param targetBaseInterface - if one of the interfaces in the root class' hierarchy implements this interface
  it will be used for generic type extraction
  @return generic interface if found, Object.class if not found.