private Class getComponentType(TypePair type) {
        Class c = null;
        Type t = type.type;
        Class raw = type.rawType;

        // First, we need to introspect class hierarchy until we found a parameterized type.
        // for sample if type is Hudson.CloudList
        // Hudson.CloudList extends Jenkins.CloudList extends DescribableList<Cloud,Descriptor<Cloud>>
        // we need to get t = DescribableList<?,?> to actually retrieve component type
        while (t instanceof Class) {
            final Type superclass = ((Class) t).getGenericSuperclass();
            if (superclass == null) {
                // No parameterized type in class hierarchy
                t = raw;
                break;
            }
            t = superclass;
        }

        if (t instanceof GenericArrayType) {
            // t is a parameterized array: <Foo>[]
            GenericArrayType at = (GenericArrayType) t;
            t = at.getGenericComponentType();
        }
        while (t instanceof ParameterizedType) {
            // t is parameterized `Some<Foo>`
            ParameterizedType pt = (ParameterizedType) t;

            t = pt.getActualTypeArguments()[0];
            if (t instanceof WildcardType) {
                // pt is Some<? extends Foo>
                t = ((WildcardType) t).getUpperBounds()[0];
                if (t == Object.class) {
                    // pt is Some<?>, so we actually want "Some"
                    t = pt.getRawType();
                }
            }
        }

        while (c == null) {
            if (t instanceof Class) {
                c = (Class) t;
            } else if (t instanceof TypeVariable) {

                // t is declared as parameterized t
                // unfortunately, java reflection doesn't allow to get the actual parameter t
                // so, if superclass it parameterized, we assume parameter t match
                // i.e target is Foo extends AbstractFoo<Bar> with
                // public abstract class AbstractFoo<T> { void setBar(T bar) }
                final Type superclass = getTarget().getGenericSuperclass();
                if (superclass instanceof ParameterizedType) {
                    final ParameterizedType psc = (ParameterizedType) superclass;
                    t = psc.getActualTypeArguments()[0];
                } else {
                    c = (Class) ((TypeVariable) t).getBounds()[0];
                }
            } else {
                return null;
            }
        }

        if (c.isArray()) {
            c = c.getComponentType();
        }

        return c;
    }
Introspect the actual component type of a collection|array {@link Type}.
plugin/src/main/java/io/jenkins/plugins/casc/BaseConfigurator.java