public static boolean isAssignable(Class<?>[] classArray, Class<?>[] toClassArray, final boolean autoboxing) { if (classArray.length != toClassArray.length) return false; for (int i = 0; i < classArray.length; i++) { if (!isAssignable(classArray[i], toClassArray[i], autoboxing)) return false; } return true; }
public static <T> Constructor<T> getMatchingConstructor(final Class<T> cls, final Class<?>... parameterTypes) { // see if we can find the constructor directly // most of the time this works and it's much faster try { final Constructor<T> ctor = cls.getConstructor(parameterTypes); return ctor; } catch (final NoSuchMethodException e) { } // return best match: Constructor<T> result = null; final Constructor<?>[] ctors = cls.getConstructors(); for (Constructor<?> ctor : ctors) { // compare parameters if (isAssignable(parameterTypes, ctor.getParameterTypes(), true)) { if (result == null || compareParameterTypes(ctor.getParameterTypes(), result.getParameterTypes(), parameterTypes) < 0) result = (Constructor<T>) ctor; } } return result; }
private static float getObjectTransformationCost(Class<?> srcClass, final Class<?> destClass) { if (destClass.isPrimitive()) { return getPrimitivePromotionCost(srcClass, destClass); } float cost = 0.0f; while (srcClass != null && !destClass.equals(srcClass)) { if (destClass.isInterface() && isAssignable(srcClass, destClass, true)) { // slight penalty for interface match. // we still want an exact match to override an interface match, // but // an interface match should override anything where we have to // get a superclass. cost += 0.25f; break; } cost++; srcClass = srcClass.getSuperclass(); } /* * If the destination class is null, we've travelled all the way up to * an Object match. We'll penalize this by adding 1.5 to the cost. */ if (srcClass == null) { cost += 1.5f; } return cost; }