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; // result of comparison
        
        // compare fix args
        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; // ambiguous
            }
        }
        
        // compare varargs of the shorter signature against fixargs of other
        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) {
            // compare remaining fixArgs of b
            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; // ambiguous
                }
            }
        }
        if (b_varArgs && b_fixLen < a_fixLen) {
            // compare remaining fixArgs of a
            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; // ambiguous
                }
            }
        }
        
        boolean a_varArgsUsed = a_varArgs && argTypes.length > a_fixLen;
        boolean b_varArgsUsed = b_varArgs && argTypes.length > b_fixLen;
        if (a_varArgsUsed && b_varArgsUsed) {
            // if var args are needed, compare them
            int newC = compareParameter(a_varType, b_varType);
            if (newC != 0 && newC != c) {
                if (c == 0) c = newC;
                else return 0; // ambiguous
            }
        }
        if (c == 0) {
            // if still equal, more fix args wins
            if (a_fixLen > b_fixLen) {
                return -1;
            } else if (b_fixLen > a_fixLen) {
                return  1;
            }
        }
        return c;
    }
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 ; }
Compares two signatures against a reference signature, according to
the rules by which Java resolves method overloading.
It is assumed that both signatures have the same
{@linkplain #applicability(java.lang.Class[], boolean) applicability level}.
@return {@code <0}: a is more specific;
{@code >0}: b is more specific;
{@code =0}: ambiguous