mardi 28 juin 2016

How to check if a method overrides a method of a given interface?

Assume we have the following interface and implementations:

interface Matcher<T>{
     boolean matches(T arg);
}

class NumberMatcher<T extends Number> implements Matcher<T>{
    @Override
    public boolean matches(T arg){...}
}

class StringMatcher extends Matcher<String>{
   @Override 
   public boolean matches(String arg){ ...}
}

class CustomMatcher extends NumberMatcher<Integer> {
    public boolean matches(String arg){...}

    @Override
    public boolean matches(Integer arg){...}
}

What I need is the type of the parameter of the matches(T) method of a given Matcher implementation.

NumberMatcher numberMatcher = new NumberMatcher<Long>();
StringMatcher stringMatcher = new StringMatcher();
CustomMatcher customMatcher = new CustomMatcher();
Matcher<Date> dateMatcher = new Matcher<Date>(){...};

getArgumentType(numberMatcher) // should return Number.class
getArgumentType(stringMatcher) // should return String.class
getArgumentType(customMatcher) // should return Integer.class
getArgumentType(dateMatcher ) // should return Object.class

Here is a implementation that works except of the CustomMatcher case, cause it fails to detect the overriden matches(..) method and returns String.class instead of Integer.class.

Class<?> getArgumentType(Matcher<?> matcher) {
    Method[] methods = matcher.getClass().getMethods();
    for (Method method : methods) {
        if (isMatchesMethod(method)) {
            return method.getParameterTypes()[0];
        }

    }
    throw new NoSuchMethodError("Method 'matches(T)' not found!");
}

private boolean isMatchesMethod(Method method) {
    if (!isPublic(method.getModifiers()))
        return false;

    if (method.getParameterCount() != 1)
        return false;

    return method.getName().equals("matches");

}





Aucun commentaire:

Enregistrer un commentaire