public static boolean isSuperType ( Type superType , Type subType ) { if ( superType instanceof ParameterizedType || superType instanceof Class || superType instanceof GenericArrayType ) { Class < ? > superClass = erase ( superType ) ; Type mappedSubType = getExactSuperType ( capture ( subType ) , superClass ) ; if ( mappedSubType == null ) { return false ; } else if ( superType instanceof Class < ? > ) { return true ; } else if ( mappedSubType instanceof Class < ? > ) { // TODO treat supertype by being raw type differently ("supertype, but with warnings") return true ; // class has no parameters, or it's a raw type } else if ( mappedSubType instanceof GenericArrayType ) { Type superComponentType = getArrayComponentType ( superType ) ; assert superComponentType != null ; Type mappedSubComponentType = getArrayComponentType ( mappedSubType ) ; assert mappedSubComponentType != null ; return isSuperType ( superComponentType , mappedSubComponentType ) ; } else { assert mappedSubType instanceof ParameterizedType ; ParameterizedType pMappedSubType = ( ParameterizedType ) mappedSubType ; assert pMappedSubType . getRawType ( ) == superClass ; ParameterizedType pSuperType = ( ParameterizedType ) superType ; Type [ ] superTypeArgs = pSuperType . getActualTypeArguments ( ) ; Type [ ] subTypeArgs = pMappedSubType . getActualTypeArguments ( ) ; assert superTypeArgs . length == subTypeArgs . length ; for ( int i = 0 ; i < superTypeArgs . length ; i ++ ) { if ( ! contains ( superTypeArgs [ i ] , subTypeArgs [ i ] ) ) { return false ; } } // params of the class itself match, so if the owner types are supertypes too, it's a supertype. return pSuperType . getOwnerType ( ) == null || isSuperType ( pSuperType . getOwnerType ( ) , pMappedSubType . getOwnerType ( ) ) ; } } else if ( superType instanceof CaptureType ) { if ( superType . equals ( subType ) ) return true ; for ( Type lowerBound : ( ( CaptureType ) superType ) . getLowerBounds ( ) ) { if ( isSuperType ( lowerBound , subType ) ) { return true ; } } return false ; } else if ( superType instanceof GenericArrayType ) { return isArraySupertype ( superType , subType ) ; } else { throw new RuntimeException ( "not implemented: " + superType . getClass ( ) ) ; } }
Checks if the capture of subType is a subtype of superType