@Nullable public InstanceFactory findInstanceFactory(@Nonnull Type mockedType) { InstanceFactory instanceFactory = mockedTypesAndInstances.get(mockedType); if (instanceFactory != null) { return instanceFactory; } Class<?> mockedClass = getClassType(mockedType); //noinspection ReuseOfLocalVariable instanceFactory = mockedTypesAndInstances.get(mockedClass); if (instanceFactory != null) { return instanceFactory; } boolean abstractType = mockedClass.isInterface() || isAbstract(mockedClass.getModifiers()); for (Entry<Type, InstanceFactory> entry : mockedTypesAndInstances.entrySet()) { Type registeredMockedType = entry.getKey(); Class<?> registeredMockedClass = getClassType(registeredMockedType); if (abstractType) { registeredMockedClass = getMockedClassOrInterfaceType(registeredMockedClass); } if (mockedClass.isAssignableFrom(registeredMockedClass)) { instanceFactory = entry.getValue(); break; } } return instanceFactory; }
public boolean conformsTo(Type t) { if (t instanceof ClassAny) { ClassAny ca = (ClassAny) t; Class otherClass = ca.c; return otherClass.isAssignableFrom(c); } else { return false; } }
public static int nextDelegate(Object[] beans, Class<?>[] apis, int index) { for (index--; index >= 0; index--) { for (Class<?> api : apis) { if (api.isAssignableFrom(beans[index].getClass())) return index; } } return index; }
public static Field findAssignableField(Class clazz, Class type, String name) throws NoSuchFieldException { final ArrayList<Field> fields = collectFields(clazz); for (Field each : fields) { if (name.equals(each.getName()) && type.isAssignableFrom(each.getType())) return each; } throw new NoSuchFieldException("Class: " + clazz + " name: " + name + " type: " + type); }
public void mapToType(Class<?> type) { if (!targetType.isAssignableFrom(type)) { throw new IllegalArgumentException( String.format( "requested wrapper type '%s' is not assignable to target type '%s'.", type.getSimpleName(), targetType.getSimpleName())); } wrapperType = type; }
/** * Determine which of two signatures is the closer fit. Returns one of PREFERENCE_EQUAL, * PREFERENCE_FIRST_ARG, PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS. */ private static int preferSignature( Object[] args, Class<?>[] sig1, boolean vararg1, Class<?>[] sig2, boolean vararg2) { int totalPreference = 0; for (int j = 0; j < args.length; j++) { Class<?> type1 = vararg1 && j >= sig1.length ? sig1[sig1.length - 1] : sig1[j]; Class<?> type2 = vararg2 && j >= sig2.length ? sig2[sig2.length - 1] : sig2[j]; if (type1 == type2) { continue; } Object arg = args[j]; // Determine which of type1, type2 is easier to convert from arg. int rank1 = NativeJavaObject.getConversionWeight(arg, type1); int rank2 = NativeJavaObject.getConversionWeight(arg, type2); int preference; if (rank1 < rank2) { preference = PREFERENCE_FIRST_ARG; } else if (rank1 > rank2) { preference = PREFERENCE_SECOND_ARG; } else { // Equal ranks if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) { if (type1.isAssignableFrom(type2)) { preference = PREFERENCE_SECOND_ARG; } else if (type2.isAssignableFrom(type1)) { preference = PREFERENCE_FIRST_ARG; } else { preference = PREFERENCE_AMBIGUOUS; } } else { preference = PREFERENCE_AMBIGUOUS; } } totalPreference |= preference; if (totalPreference == PREFERENCE_AMBIGUOUS) { break; } } return totalPreference; }
private static boolean typeMatches(Class<?> foundType, Class<?> expectedType) { if (foundType == null) return true; if (expectedType.isAssignableFrom(foundType)) return true; if (isPrimitiveType(expectedType.getName()) && foundType.equals(getWrapper(expectedType.getName()))) return true; if (isPrimitiveType(foundType.getName()) && expectedType.equals(getWrapper(foundType.getName()))) return true; if (isNumberType(foundType) && isNumberType(expectedType)) return true; return false; }
/** * Return the type distance between the child and parent types. The child type must be a subtype * of the parent. The type distance between a class and itself is 0; the distance from a class to * one of its immediate supertypes (superclass or a directly implemented interface) is 1; deeper * distances are computed recursively. * * @param child The child type * @param parent The parent type * @return The type distance * @throws IllegalArgumentException if {@code child} is not a subtype of {@code parent}. */ public static int getTypeDistance(@Nonnull Class<?> child, @Nonnull Class<?> parent) { Preconditions.notNull("child class", child); Preconditions.notNull("parent class", parent); if (child.equals(parent)) { // fast-path same-class tests return 0; } else if (!parent.isAssignableFrom(child)) { // if child does not extend from the parent, return -1 throw new IllegalArgumentException("child not a subclass of parent"); } else if (!parent.isInterface()) { // if the parent is not an interface, we only need to follower superclasses int distance = 0; Class<?> cur = child; while (!cur.equals(parent)) { distance++; cur = cur.getSuperclass(); } return distance; } else { // worst case, recursively compute the type // recursion is safe, as types aren't too deep except in crazy-land int minDepth = Integer.MAX_VALUE; Class<?> sup = child.getSuperclass(); if (sup != null && parent.isAssignableFrom(sup)) { minDepth = getTypeDistance(sup, parent); } for (Class<?> iface : child.getInterfaces()) { if (parent.isAssignableFrom(iface)) { int d = getTypeDistance(iface, parent); if (d < minDepth) { minDepth = d; } } } // minDepth now holds the depth of the superclass with shallowest depth return minDepth + 1; } }
public <T> T nodeByTypeElement(Class<T> baseType) { int len = children.size(); for (int i = 0; i < len; i++) { Child child = children.get(i); if (child instanceof NodeChild) { NodeChild nc = (NodeChild) child; if (model.elements.containsKey(nc.name)) continue; // match with named if (baseType.isAssignableFrom(nc.dom.getImplementationClass())) return baseType.cast(nc.dom.get()); } } return null; }
private Object replace(Class<?> type, ApplicableGenerator generator, boolean alternative) { for (Creator<?> creator : creators) { ParameterizedType generic = (ParameterizedType) creator.getClass().getGenericInterfaces()[0]; Class<?> restrained = generic.getActualTypeArguments()[0] instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType() : (Class<?>) generic.getActualTypeArguments()[0]; if (type.isAssignableFrom(restrained)) { return creator.create(); } } return generator.generate(type, alternative); }
private Object generate(Class<?> type, boolean alternative) { for (Generator<?> generator : generators) { ParameterizedType generic = (ParameterizedType) generator.getClass().getGenericInterfaces()[0]; Class<?> restrained = generic.getActualTypeArguments()[0] instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType() : (Class<?>) generic.getActualTypeArguments()[0]; if (type.isAssignableFrom(restrained)) { type = generator.generate(); } } return type == String.class ? alternative ? OTHER_STRING : DEFAULT_STRING : mock(type); }
/** * Picks up all node elements that are assignable to the given type, except those who are matched * by other named elements in the model. * * <p>Used to implement {@code FromElement("*")}. */ public List<Dom> domNodeByTypeElements(Class baseType) { List<Dom> r = new ArrayList<Dom>(); int len = children.size(); for (int i = 0; i < len; i++) { Child child = children.get(i); if (child instanceof NodeChild) { NodeChild nc = (NodeChild) child; if (model.elements.containsKey(nc.name)) continue; // match with named if (baseType.isAssignableFrom(nc.dom.getImplementationClass())) r.add(nc.dom); } } return r; }
public static Class<?> commonSubType(Collection<?> objects) { Iterator<?> iterator = objects.iterator(); if (!iterator.hasNext()) return null; Class<?> result = null; while (iterator.hasNext()) { Object candidate = iterator.next(); if (candidate != null) { Class<?> candidateClass = candidate.getClass(); if (result == null) result = candidateClass; else if (candidateClass != result && result.isAssignableFrom(candidateClass)) result = candidateClass; } } return result; }
/** Check if the given collection is a uniform collection of the given type. */ public static boolean isUniformCollection(Collection<?> c, Class<?> e) { if (e == null) { throw new IllegalArgumentException("Null reference type"); } if (c == null) { throw new IllegalArgumentException("Null collection"); } if (c.isEmpty()) { return false; } for (Object o : c) { if (o == null || !e.isAssignableFrom(o.getClass())) { return false; } } return true; }
public static void setPropertyValue( Object bean, String propertyName, Object propertyValue, boolean required, boolean autoConvert) { Method writeMethod = null; try { Class<?> beanClass = bean.getClass(); PropertyDescriptor propertyDescriptor = getPropertyDescriptor(beanClass, propertyName); if (propertyDescriptor == null) if (required) throw new ConfigurationError( beanClass + " does not have a property '" + propertyName + "'"); else return; writeMethod = propertyDescriptor.getWriteMethod(); if (writeMethod == null) throw new UnsupportedOperationException( "Cannot write read-only property '" + propertyDescriptor.getName() + "' of " + beanClass); Class<?> propertyType = propertyDescriptor.getPropertyType(); if (propertyValue != null) { Class<?> argType = propertyValue.getClass(); if (!propertyType.isAssignableFrom(argType) && !isWrapperTypeOf(propertyType, propertyValue) && !autoConvert) throw new IllegalArgumentException( "ArgumentType mismatch: expected " + propertyType.getName() + ", found " + propertyValue.getClass().getName()); else propertyValue = AnyConverter.convert(propertyValue, propertyType); } writeMethod.invoke(bean, propertyValue); } catch (IllegalAccessException e) { throw ExceptionMapper.configurationException(e, writeMethod); } catch (InvocationTargetException e) { throw ExceptionMapper.configurationException(e, writeMethod); } }
/** * Get the type that is provided by a given implementation of {@link Provider}. * * @param providerClass The provider's class * @return The provided class type * @throws IllegalArgumentException if the class doesn't actually implement Provider */ public static Class<?> getProvidedType(Class<? extends Provider<?>> providerClass) { com.google.common.base.Preconditions.checkArgument( Provider.class.isAssignableFrom(providerClass), "class is not Provider class"); Map<TypeVariable<?>, Type> bindings = TypeUtils.getTypeArguments(providerClass, Provider.class); if (!bindings.containsKey(PROVIDER_TYPE_VAR)) { throw new IllegalArgumentException( "Class provided by " + providerClass.getName() + " is generic"); } final Class<?> inferredType = TypeUtils.getRawType(bindings.get(PROVIDER_TYPE_VAR), null); try { final Class<?> observedType = providerClass.getMethod("get").getReturnType(); if (inferredType != null && inferredType.isAssignableFrom(observedType)) { return observedType; } else { return inferredType; } } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Class does not implement get()"); } }
/** * This method returns a <tt>Class</tt> for a helper which can handle the list of distributions * specified by <tt>seq1</tt>. We maintain a cache of recently-loaded helpers, so check the cache * before going to the trouble of searching for a helper. The cache is blown away every * <tt>HELPER_CACHE_REFRESH</tt> seconds. * * <p>If we can't find a helper in the cache, we must search through the list of available helpers * to find an appropriate one. First try to find helper using class sequence as specified by * <tt>seq</tt>. Whether or not that succeeds, promote any <tt>Gaussian</tt> in the sequence to * <tt>MixGaussians</tt>, and try again. If we get a better match on the second try, return the * helper thus found. */ public static Class find_helper_class(Vector seq1, String helper_type) throws ClassNotFoundException { // Let's see if an appropriate helper is in the cache. // If the cache is too old, empty it and search for the helper anew. if (System.currentTimeMillis() - cache_timestamp > HELPER_CACHE_REFRESH) { helper_cache = new Hashtable(); cache_timestamp = System.currentTimeMillis(); // Go on and search for appropriate helper. } else { HelperCacheKey key = new HelperCacheKey(helper_type, seq1); Class helper_class = (Class) helper_cache.get(key); if (helper_class != null) { if (Global.debug > -1) System.err.println( "PiHelperLoader.find_helper_class: found helper class: " + helper_class + "; no need to search."); return helper_class; } // else no luck; we have to search for helper. } // Well, we didn't find a helper in the cache, so let's go to work. if (Global.debug > -1) System.err.println( "PiHelperLoader.find_helper_class: DID NOT FIND HELPER CLASS; NOW SEARCH."); Class c1 = null, c2 = null; ClassNotFoundException cnfe1 = null, cnfe2 = null; int[] class_score1 = new int[1], count_score1 = new int[1]; int[] class_score2 = new int[1], count_score2 = new int[1]; try { c1 = find_helper_class1(seq1, helper_type, class_score1, count_score1); } catch (ClassNotFoundException e) { cnfe1 = e; } // hang on, we may need to re-throw later. Class gaussian_class = Class.forName("riso.distributions.Gaussian"); MixGaussians mog = new MixGaussians(1, 1); Vector seq2 = new Vector(seq1.size()); for (int i = 0; i < seq1.size(); i++) if (gaussian_class.isAssignableFrom((Class) seq1.elementAt(i))) seq2.addElement(mog.getClass()); else seq2.addElement(seq1.elementAt(i)); try { c2 = find_helper_class1(seq2, helper_type, class_score2, count_score2); } catch (ClassNotFoundException e) { cnfe2 = e; } if (cnfe1 == null && cnfe2 == null) { // Both matched; see which one fits better. // Break ties in favor of the helper for non-promoted messages. if (class_score1[0] >= class_score2[0] || (class_score1[0] == class_score2[0] && count_score1[0] >= count_score2[0])) { if (Global.debug > 1) System.err.println( "\taccept helper " + c1 + " for non-promoted classes instead of " + c2); if (Global.debug > 1) System.err.println( "\t\t" + class_score1[0] + ", " + class_score2[0] + "; " + count_score1[0] + ", " + count_score2[0]); helper_cache.put(new HelperCacheKey(helper_type, seq1), c1); return c1; } else { if (Global.debug > 1) System.err.println("\taccept helper " + c2 + " for promoted classes instead of " + c1); if (Global.debug > 1) System.err.println( "\t\t" + class_score1[0] + ", " + class_score2[0] + "; " + count_score1[0] + ", " + count_score2[0]); helper_cache.put(new HelperCacheKey(helper_type, seq1), c2); return c2; } } else if (cnfe1 == null && cnfe2 != null) { // Only the first try matched, return it. helper_cache.put(new HelperCacheKey(helper_type, seq1), c1); return c1; } else if (cnfe1 != null && cnfe2 == null) { // Only the second try matched, return it. helper_cache.put(new HelperCacheKey(helper_type, seq1), c2); return c2; } else { // Neither try matched. Re-throw the exception generated by the first try. throw cnfe1; } }
protected void _resolveBindings(Type t) { if (t == null) return; Class<?> raw; if (t instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) t; Type[] args = pt.getActualTypeArguments(); if (args != null && args.length > 0) { Class<?> rawType = (Class<?>) pt.getRawType(); TypeVariable<?>[] vars = rawType.getTypeParameters(); if (vars.length != args.length) { throw new IllegalArgumentException( "Strange parametrized type (in class " + rawType.getName() + "): number of type arguments != number of type parameters (" + args.length + " vs " + vars.length + ")"); } for (int i = 0, len = args.length; i < len; ++i) { TypeVariable<?> var = vars[i]; String name = var.getName(); if (_bindings == null) { _bindings = new LinkedHashMap<String, JavaType>(); } else { /* 24-Mar-2010, tatu: Better ensure that we do not overwrite something * collected earlier (since we descend towards super-classes): */ if (_bindings.containsKey(name)) continue; } // first: add a placeholder to prevent infinite loops _addPlaceholder(name); // then resolve type _bindings.put(name, _typeFactory._constructType(args[i], this)); } } raw = (Class<?>) pt.getRawType(); } else if (t instanceof Class<?>) { raw = (Class<?>) t; /* [JACKSON-677]: If this is an inner class then the generics are defined on the * enclosing class so we have to check there as well. We don't * need to call getEnclosingClass since anonymous classes declare * generics */ _resolveBindings(raw.getDeclaringClass()); /* 24-Mar-2010, tatu: Can not have true generics definitions, but can * have lower bounds ("<T extends BeanBase>") in declaration itself */ TypeVariable<?>[] vars = raw.getTypeParameters(); if (vars != null && vars.length > 0) { JavaType[] typeParams = null; if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) { typeParams = _typeFactory.findTypeParameters(_contextType, raw); } for (int i = 0; i < vars.length; i++) { TypeVariable<?> var = vars[i]; String name = var.getName(); Type varType = var.getBounds()[0]; if (varType != null) { if (_bindings == null) { _bindings = new LinkedHashMap<String, JavaType>(); } else { // and no overwriting... if (_bindings.containsKey(name)) continue; } _addPlaceholder(name); // to prevent infinite loops if (typeParams != null) { _bindings.put(name, typeParams[i]); } else { _bindings.put(name, _typeFactory._constructType(varType, this)); } } } } } else { // probably can't be any of these... so let's skip for now // if (type instanceof GenericArrayType) { // if (type instanceof TypeVariable<?>) { // if (type instanceof WildcardType) { return; } // but even if it's not a parameterized type, its super types may be: _resolveBindings(raw.getGenericSuperclass()); for (Type intType : raw.getGenericInterfaces()) { _resolveBindings(intType); } }
/** * Aspect implementation which executes grid-enabled methods on remote nodes. * * @param invoc Method invocation instance provided by JBoss AOP framework. * @return Method execution result. * @throws Throwable If method execution failed. */ @SuppressWarnings({ "ProhibitedExceptionDeclared", "ProhibitedExceptionThrown", "CatchGenericClass", "unchecked" }) @Bind( pointcut = "execution(* *->@org.gridgain.grid.gridify.Gridify(..))", cflow = "org.gridgain.grid.gridify.aop.jboss.GridifyJbossAspect.CFLOW_STACK") public Object gridify(MethodInvocation invoc) throws Throwable { Method mtd = invoc.getMethod(); Gridify ann = mtd.getAnnotation(Gridify.class); assert ann != null : "Intercepted method does not have gridify annotation."; // Since annotations in Java don't allow 'null' as default value // we have accept an empty string and convert it here. // NOTE: there's unintended behavior when user specifies an empty // string as intended grid name. // NOTE: the 'ann.gridName() == null' check is added to mitigate // annotation bugs in some scripting languages (e.g. Groovy). String gridName = F.isEmpty(ann.gridName()) ? null : ann.gridName(); if (G.state(gridName) != STARTED) { throw new GridException("Grid is not locally started: " + gridName); } // Initialize defaults. GridifyArgument arg = new GridifyArgumentAdapter( mtd.getDeclaringClass(), mtd.getName(), mtd.getParameterTypes(), invoc.getArguments(), invoc.getTargetObject()); if (!ann.interceptor().equals(GridifyInterceptor.class)) { // Check interceptor first. if (!ann.interceptor().newInstance().isGridify(ann, arg)) { return invoc.invokeNext(); } } if (!ann.taskClass().equals(GridifyDefaultTask.class) && ann.taskName().length() > 0) { throw new GridException( "Gridify annotation must specify either Gridify.taskName() or " + "Gridify.taskClass(), but not both: " + ann); } try { Grid grid = G.grid(gridName); // If task class was specified. if (!ann.taskClass().equals(GridifyDefaultTask.class)) { return grid.execute( (Class<? extends GridTask<GridifyArgument, Object>>) ann.taskClass(), arg, ann.timeout()) .get(); } // If task name was not specified. if (ann.taskName().length() == 0) { return grid.execute( new GridifyDefaultTask(invoc.getActualMethod().getDeclaringClass()), arg, ann.timeout()) .get(); } // If task name was specified. return grid.execute(ann.taskName(), arg, ann.timeout()).get(); } catch (Throwable e) { for (Class<?> ex : invoc.getMethod().getExceptionTypes()) { // Descend all levels down. Throwable cause = e.getCause(); while (cause != null) { if (ex.isAssignableFrom(cause.getClass())) { throw cause; } cause = cause.getCause(); } if (ex.isAssignableFrom(e.getClass())) { throw e; } } throw new GridifyRuntimeException("Undeclared exception thrown: " + e.getMessage(), e); } }
private Object getParam( final Class<?> pClass, final String pName, final ParamType pType, final String pXpath, final HttpMessage pMessage) throws XmlException { Object result = null; switch (pType) { case GET: result = getParamGet(pName, pMessage); break; case POST: result = getParamPost(pName, pMessage); break; case QUERY: result = getParamGet(pName, pMessage); if (result == null) { result = getParamPost(pName, pMessage); } break; case VAR: result = mPathParams.get(pName); break; case XPATH: result = getParamXPath(pClass, pXpath, pMessage.getBody()); break; case BODY: result = getBody(pClass, pMessage); break; case ATTACHMENT: result = getAttachment(pClass, pName, pMessage); break; case PRINCIPAL: { final Principal principal = pMessage.getUserPrincipal(); if (pClass.isAssignableFrom(String.class)) { result = principal.getName(); } else { result = principal; } break; } } // XXX generizice this and share the same approach to unmarshalling in ALL code // TODO support collection/list parameters if ((result != null) && (!pClass.isInstance(result))) { if ((Types.isPrimitive(pClass) || (Types.isPrimitiveWrapper(pClass))) && (result instanceof String)) { try { result = Types.parsePrimitive(pClass, ((String) result)); } catch (NumberFormatException e) { throw new HttpResponseException( HttpServletResponse.SC_BAD_REQUEST, "The argument given is invalid", e); } } else if (Enum.class.isAssignableFrom(pClass)) { @SuppressWarnings({"rawtypes"}) final Class clazz = pClass; @SuppressWarnings("unchecked") final Enum<?> tmpResult = Enum.valueOf(clazz, result.toString()); result = tmpResult; } else if (result instanceof Node) { XmlDeserializer factory = pClass.getAnnotation(XmlDeserializer.class); if (factory != null) { try { result = factory .value() .newInstance() .deserialize(XmlStreaming.newReader(new DOMSource((Node) result))); } catch (IllegalAccessException | InstantiationException e) { throw new XmlException(e); } } else { result = JAXB.unmarshal(new DOMSource((Node) result), pClass); } } else { final String s = result.toString(); // Only wrap when we don't start with < final char[] requestBody = (s.startsWith("<") ? s : "<wrapper>" + s + "</wrapper>").toCharArray(); if (requestBody.length > 0) { result = JAXB.unmarshal(new CharArrayReader(requestBody), pClass); } else { result = null; } } } return result; }
/** * Determines if the suspected super type is assignable from the suspected sub type. * * @param suspectedSuperType e.g. {@code GenericDAO<Pet, String>} * @param suspectedSubType e.g. {@code PetDAO extends GenericDAO<Pet,String>} * @return true if (sourceType)targetClass is a valid cast */ public static boolean isAssignableFrom(Type suspectedSuperType, Type suspectedSubType) { final Class suspectedSuperClass = asClass(suspectedSuperType); final Class suspectedSubClass = asClass(suspectedSubType); // The raw types need to be compatible. if (!suspectedSuperClass.isAssignableFrom(suspectedSubClass)) { return false; } // From this point we know that the raw types are assignable. // We need to figure out what the generic parameters in the targetClass are // as they pertain to the sourceType. if (suspectedSuperType instanceof WildcardType) { // ? extends Number // needs to match all the bounds (there will only be upper bounds or lower bounds for (Type t : ((WildcardType) suspectedSuperType).getUpperBounds()) { if (!isAssignableFrom(t, suspectedSubType)) return false; } for (Type t : ((WildcardType) suspectedSuperType).getLowerBounds()) { if (!isAssignableFrom(suspectedSubType, t)) return false; } return true; } Type curType = suspectedSubType; Class curClass; while (curType != null && !curType.equals(Object.class)) { curClass = asClass(curType); if (curClass.equals(suspectedSuperClass)) { final Type resolved = resolve(curType, suspectedSubType); if (suspectedSuperType instanceof Class) { if (resolved instanceof Class) return suspectedSuperType.equals(resolved); // They may represent the same class, but the suspectedSuperType is not parameterized. The // parameter // types default to Object so they must be a match. // e.g. Pair p = new StringLongPair(); // Pair p = new Pair<? extends Number, String> return true; } if (suspectedSuperType instanceof ParameterizedType) { if (resolved instanceof ParameterizedType) { final Type[] type1Arguments = ((ParameterizedType) suspectedSuperType).getActualTypeArguments(); final Type[] type2Arguments = ((ParameterizedType) resolved).getActualTypeArguments(); if (type1Arguments.length != type2Arguments.length) return false; for (int i = 0; i < type1Arguments.length; ++i) { if (!isAssignableFrom(type1Arguments[i], type2Arguments[i])) return false; } return true; } } else if (suspectedSuperType instanceof GenericArrayType) { if (resolved instanceof GenericArrayType) { return isAssignableFrom( ((GenericArrayType) suspectedSuperType).getGenericComponentType(), ((GenericArrayType) resolved).getGenericComponentType()); } } return false; } final Type[] types = curClass.getGenericInterfaces(); for (Type t : types) { final Type resolved = resolve(t, suspectedSubType); if (isAssignableFrom(suspectedSuperType, resolved)) return true; } curType = curClass.getGenericSuperclass(); } return false; }