JavaSignatureComparator { public int compareSpecificness(final Class<?>[] a, boolean a_varArgs, final Class<?>[] b, boolean b_varArgs) { final int a_fixLen = a.length - (a_varArgs ? 1 : 0); final int b_fixLen = b.length - (b_varArgs ? 1 : 0); final int fixLen = Math.min(a_fixLen, b_fixLen); int c = 0; for (int i = 0; i < fixLen; i++) { int newC = compareParameter(a[i], b[i]); if (newC != 0 && newC != c) { if (c == 0) c = newC; else return 0; } } Class<?> a_varType = a_varArgs ? a[a_fixLen] : null; Class<?> b_varType = b_varArgs ? b[b_fixLen] : null; if (a_varArgs && a_fixLen < b_fixLen) { for (int i = fixLen; i < b_fixLen; i++) { int newC = compareParameter(a_varType, b[i]); if (newC != 0 && newC != c) { if (c == 0) c = newC; else return 0; } } } if (b_varArgs && b_fixLen < a_fixLen) { for (int i = fixLen; i < a_fixLen; i++) { int newC = compareParameter(a[i], b_varType); if (newC != 0 && newC != c) { if (c == 0) c = newC; else return 0; } } } boolean a_varArgsUsed = a_varArgs && argTypes.length > a_fixLen; boolean b_varArgsUsed = b_varArgs && argTypes.length > b_fixLen; if (a_varArgsUsed && b_varArgsUsed) { int newC = compareParameter(a_varType, b_varType); if (newC != 0 && newC != c) { if (c == 0) c = newC; else return 0; } } if (c == 0) { if (a_fixLen > b_fixLen) { return -1; } else if (b_fixLen > a_fixLen) { return 1; } } return c; } JavaSignatureComparator(Class<?>... argTypes); Class<?>[] getReferenceSignature(); int compareSpecificness(final Class<?>[] a, boolean a_varArgs, final Class<?>[] b, boolean b_varArgs); int applicability(final Class<?>[] paramTypes, boolean varArgs); static final int MATCH; static final int MATCH_WILDCARD; static final int MATCH_BOXING; static final int MATCH_VARARGS; static final int NO_MATCH; }
@Test public void test_specificness_simple() { Class[] args = {Integer.class}; Class[] params1 = {Object.class}; Class[] params2 = {Number.class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, false, params2, false); assertThat(spec, is(greaterThan(0))); }
@Test public void test_specificness_ambiguous() { Class[] args = {Integer.class, Integer.class}; Class[] params1 = {Object.class, Number.class}; Class[] params2 = {Number.class, Object.class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, false, params2, false); assertThat(spec, is(0)); }
@Test public void test_specificness_varArgs() { Class[] args = {String.class, Integer.class}; Class[] params1 = {String.class, Object[].class}; Class[] params2 = {String.class, Number[].class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, true, params2, true); assertThat(spec, is(greaterThan(0))); }
@Test public void test_specificness_varArgs_unused_ambiguous() { Class[] args = {String.class}; Class[] params1 = {String.class, Object[].class}; Class[] params2 = {String.class, Number[].class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, true, params2, true); assertThat(spec, is(0)); }
@Test public void test_specificness_varArgs_useMoreFixed() { Class[] args = {String.class, String.class, String.class}; Class[] params1 = {String.class, String.class, String[].class}; Class[] params2 = {String.class, String[].class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, true, params2, true); assertThat(spec, is(lessThan(0))); }
@Test public void test_specificness_any() { Class[] args = null; Class[] params1 = {Object.class}; Class[] params2 = {Number.class}; JavaSignatureComparator jsCmp = new JavaSignatureComparator(args); int spec = jsCmp.compareSpecificness(params1, false, params2, false); assertThat(spec, is(greaterThan(0))); }