// 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 -1 = 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; // char can be converted to byte if (b == byte.class) ret a == char.class ? 1 : Int.MAX_VALUE; // byte can be converted to char if (b == char.class) ret a == byte.class ? 1 : Int.MAX_VALUE; // byte can be converted to short if (b == short.class) ret a == byte.class ? 1 : 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 ? 1 : 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 ? 1 : 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 ? 1 : Int.MAX_VALUE; // all primitive types except bool can be converted to double ret a != bool.class ? 1 : 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 is not primitive if (a.isPrimitive()) ret primitiveToBoxedType(a) == b? 1 : Int.MAX_VALUE; // both types are not primitive if (b.isAssignableFrom(a)) ret 1; } if (b == byte.class) ret else if (c == a.getClass()) {} // perfect match + if (a == byte.class) + return 1; + if (a == short.class) + return b == byte.class ? -1 : 1; + if (a == char.class) // chars are disjoint with bytes and shorts + return (b == byte.class || b == short.class) ? 0 : 1; + if (b == char.class) + return (a == byte.class || a == short.class) ? 0 : 1; + if (a == int.class) + return (b == short.class || b == byte.class) ? -1 : 1; + if (a == long.class) + return (b == float.class || b == double.class) ? 1 : -1; + if (a == float.class) + return b == double.class? 1 : -1; else if (isInstanceX(c, a)) ++score; else ret Int.MAX_VALUE; } ret score;