private static boolean isAssignableFrom ( Type from , ParameterizedType to , Map < String , Type > typeVarMap ) { if ( from == null ) { return false ; } if ( to . equals ( from ) ) { return true ; } // First figure out the class and any type information. Class < ? > clazz = getRawType ( from ) ; ParameterizedType ptype = null ; if ( from instanceof ParameterizedType ) { ptype = ( ParameterizedType ) from ; } // Load up parameterized variable info if it was parameterized. if ( ptype != null ) { Type [ ] tArgs = ptype . getActualTypeArguments ( ) ; TypeVariable < ? > [ ] tParams = clazz . getTypeParameters ( ) ; for ( int i = 0 ; i < tArgs . length ; i ++ ) { Type arg = tArgs [ i ] ; TypeVariable < ? > var = tParams [ i ] ; while ( arg instanceof TypeVariable ) { TypeVariable < ? > v = ( TypeVariable < ? > ) arg ; arg = typeVarMap . get ( v . getName ( ) ) ; } typeVarMap . put ( var . getName ( ) , arg ) ; } // check if they are equivalent under our current mapping. if ( typeEquals ( ptype , to , typeVarMap ) ) { return true ; } } for ( Type itype : clazz . getGenericInterfaces ( ) ) { if ( isAssignableFrom ( itype , to , new HashMap < String , Type > ( typeVarMap ) ) ) { return true ; } } // Interfaces didn't work, try the superclass. Type sType = clazz . getGenericSuperclass ( ) ; if ( isAssignableFrom ( sType , to , new HashMap < String , Type > ( typeVarMap ) ) ) { return true ; } return false ; }
Private recursive helper function to actually do the type - safe checking of assignability .