3
は、我々は次のインターフェイスと実装を持っていると仮定しますブリッジメソッドの宣言方法を見つけるには?
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){...}
}
私は必要なもの与えられたのMatcherの実装の一致(T)メソッドのパラメータの型です。それがオーバーライドされたマッチ(..)メソッドを検出できないとString.class
の代わりInteger.class
を返す原因ここ
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
は、CustomMatcherの例を除いて働く実装です。
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");
}
EDIT:限り、あなたが編集できるよう
interface Matcher<T>{
boolean matches(T arg);
Class<T> argumentType();
}
ちょうど参考に、明らかな解決策は、メソッドに 'getDeclaredAnnotations()'を適用することです。しかし、この場合、 '@ Override'アノテーションは実行時にアクセスできなくなるため、これは機能しません。 –
['Method.getDeclaringClass'](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#getDeclaringClass--)は役に立ちますか? – Seelenvirtuose
@Seelenvirtuose Method.getDeclaringClass()は、 'CustomMatcher'の場合には動作しません。なぜなら、宣言クラスは' Matcher'ではなく、 'NumberMatcher'です。 – Chriss