// Can a be converted to b? // score 0 = exact match // score Int.MAX_VALUE = no match // score 1 = conversion needed (boxing/unboxing or non-primitve widening) // score -2 = primitive widening needed static int typeConversionScore(Class a, Class b) { if (a == b) ret 0; if (b.isPrimitive()) { // target type is primitive if (a.isPrimitive()) { // both types are primitive // No widenings to bool if (b == bool.class) ret Int.MAX_VALUE; // No widenings to byte if (b == byte.class) ret Int.MAX_VALUE; // byte can be converted to char if (b == char.class) ret a == byte.class ? -2 : Int.MAX_VALUE; // byte can be converted to short if (b == short.class) ret a == byte.class ? -2 : Int.MAX_VALUE; // byte, char and short can be converted to int if (b == int.class) ret a == byte.class || a == char.class || a == short.class ? -2 : Int.MAX_VALUE; // byte, char, short and int can be converted to long if (b == long.class) ret a == byte.class || a == char.class || a == short.class || a == int.class ? -2 : Int.MAX_VALUE; // byte, char, short and int can be converted to float if (b == float.class) ret a == byte.class || a == char.class || a == short.class || a == int.class ? -2 : Int.MAX_VALUE; // all primitive types except bool can be converted to double ret a != bool.class ? -2 : Int.MAX_VALUE; } else { // source type is boxed - check if they're a match ret primitiveToBoxedType(b) == a ? 1 : Int.MAX_VALUE; } } else { // Target type b is not primitive. // Object type a is primitive - check for exact match if (a.isPrimitive()) ret primitiveToBoxedType(a) == b ? 1 : Int.MAX_VALUE; // BOTH TYPES ARE NOT PRIMITIVE. // if not assignable, no match if (!b.isAssignableFrom(a)) ret Int.MAX_VALUE; // if assignable, get precise score // if any is an interface, just get score 1 if (a.isInterface() || b.isInterface()) ret 1; if (a.isArray() && b.isArray()) ret typeConversionScore(a.getComponentType(), b.getComponentType())/2; // for classes, count subclass distance ret subclassDistance(a, b)*2; } }