public static < T > Class < T > findActualClassParameter ( Class clz , int parm ) { Class parm_class = null ; if ( clz . getGenericSuperclass ( ) instanceof ParameterizedType ) { Type [ ] handler_type_parms = ( ( ParameterizedType ) ( clz . getGenericSuperclass ( ) ) ) . getActualTypeArguments ( ) ; if ( handler_type_parms [ parm ] instanceof Class ) { // The handler's Iced class is not parameterized (the normal case): parm_class = ( Class ) handler_type_parms [ parm ] ; // E.g., for a Schema [0] is the impl (Iced) type; [1] is the Schema type } else if ( handler_type_parms [ parm ] instanceof TypeVariable ) { // The handler's Iced class is parameterized, e.g. to handle multiple layers of Schema classes as in ModelsHandler: TypeVariable v = ( TypeVariable ) ( handler_type_parms [ parm ] ) ; Type t = v . getBounds ( ) [ 0 ] ; // [0] or [parm] ? if ( t instanceof Class ) parm_class = ( Class ) t ; else if ( t instanceof ParameterizedType ) parm_class = ( Class ) ( ( ParameterizedType ) t ) . getRawType ( ) ; } else if ( handler_type_parms [ parm ] instanceof ParameterizedType ) { // The handler's Iced class is parameterized, e.g. to handle multiple layers of Schema classes as in ModelsHandler: parm_class = ( Class ) ( ( ParameterizedType ) ( handler_type_parms [ parm ] ) ) . getRawType ( ) ; // For a Key<Frame> this returns Key.class; see also getActualTypeArguments() } else { String msg = "Iced parameter for handler: " + clz + " uses a type parameterization scheme that we don't yet handle: " + handler_type_parms [ parm ] ; Log . warn ( msg ) ; throw H2O . fail ( msg ) ; } } else { // Superclass is not a ParameterizedType, so we just have Iced. parm_class = Iced . class ; // If the handler isn't parameterized on the Iced class then this has to be Iced. } return ( Class < T > ) parm_class ; }
Reflection helper which returns the actual class for a type parameter even if itself is parameterized .