【发布时间】:2020-09-21 14:26:45
【问题描述】:
我有 2 个类,它们的内部结构根本不重要。
class ClassA {
//...
}
class ClassB {
//...
}
我有 2 个使用这些类的谓词,假设它们看起来像这样
private Predicate<ClassA> classAPredicate() {
return Objects::nonNull;
}
private Predicate<ClassB> classBPredicate() {
return Objects::nonNull;
}
现在,我在外部库中有一个通用方法,该方法已经被许多用户使用,不幸的是,它具有非常通用的输入参数,即Object,在 90% 的情况下为Predicate。
我需要做的是通过检查传递的Predicate的类型来扩展这个方法的功能,并在此基础上执行一些操作。
public void test(Object obj) {
Predicate predicate = (Predicate)obj;
if(predicate.getClass().isAssignableFrom(ClassA.class)) {
System.out.println(predicate.test(new ClassA()));
// logic specific to Predicate<ClassA>
} else {
System.out.println(predicate.test(new ClassB()));
// logic specific to Predicate<ClassB>
}
}
但是,在测试期间,我同时通过了 Predicates 并且它失败了 Exception in thread "main" java.lang.ClassCastException:
test(classAPredicate());
test(classBPredicate());
我一直在调试,isAssignableFrom() 总是返回 false,所以这里的错误很明显。我不确定这是否是正确的方法,但我还没有想出其他任何方法。有什么方法可以检查Predicate 的类型是什么?
我知道我想要实现的并不理想,但这是当前的要求......
【问题讨论】:
-
无法针对 ClassA 或 ClassB 测试谓词,您需要查找
getGenericInterfaces或getGenericSuperclass以检查谓词所引用的类。 -
由于type erasure,您无法在运行时获取
Predicate的泛型类型参数。如果您的要求是接收没有其他信息的Predicate,然后尝试推断其泛型类型参数(没有运行时异常),那么您将不得不重新协商您的要求,因为这是不可能的。