我正在入侵一个比较深奥的图书馆,而我可能遇到了有史以来最具体的问题。我想检查是否引用某个方法m
的方法是否可以实现某些功能接口FI
,是否带有接收器参数(即m
是否属于某个类{{1 }}和C
,我想同时检查c instanceof C
和c::m
)。
在某些情况下,我已经解决了此问题...检查Arity,检查参数类型,检查返回类型,检查异常类型,处理可能的接收器参数yada yada。但是当泛型发挥作用时,它变得毛茸茸。
C::m
interface TypeMatcher {
boolean isSubtype(final Type type);
boolean isSupertype(final Type type);
static TypeMatcher.of(final Type type) {
// ...
}
}
要检查某个方法是否可以实现功能性方法,我只创建了一个class TypeVariableMatcher implements TypeMatcher {
private final TypeVariable<?> typeVariable;
private TypeMatcher binding;
TypeVariableMatcher(final TypeVariable<?> typeVariable) {
this.typeVariable = typeVariable;
}
@Override public boolean isSubtype(final Type type) {
// TODO: check bounds... how?
return check(type, TypeMatcher::isSubtype);
}
@Override public boolean isSupertype(final Type type) {
// TODO: check bounds... how?
return check(type, TypeMatcher::isSupertype);
}
private boolean check(final Type type, final BiPredicate<TypeMatcher, Type> callback) {
if (binding == null) {
binding = TypeMatcher.of(type);
return true;
}
return callback.test(binding, type);
}
}
缓存(让TypeMatcher
为cache
,然后为Map
)。然后,我只是尝试按此顺序匹配参数,返回类型和异常类型(由于varargs和可能的接收者参数等原因,它并不是那么简单,但是您会得到jist)。缓存有助于处理matcherFactory = type -> cache.computeIfAbsent(type, TypeMatcher::of)
之类的接口,但是...
如java.util.BinaryOperator
所述,这不会检查有界类型参数,因此此测试用例将失败:
// TODO
...因为interface FI<R extends Runnable> {
void fm(R r1, R r2);
}
interface C {
void cannotImplementFI(String s1, String s2);
}
被报告为String
的“超类型”,即使事实并非如此。我也不确定如何处理有界通配符:
R
也许我的方法是错误的,或者我一直在同一个问题上苦苦挣扎,却错过了一些明显的东西。任何有关如何从此处进行操作的指示都将非常可爱!!