我有Predicate<Object>
,需要等效的Predicate<Animal>
。
Predicate<Animal> provideIsSentientPredicate() {
// Won't compile -- cannot convert from Predicate<Object> to Predicate<Animal>
return Predicates.instanceOf(Human.class);
}
谓词是逆变的,因此将Predicate<Object>
转换为Predicate<Animal>
是安全的。是否有清晰易读的方式从Predicate<Object>
转换为Predicate<Animal>
(例如,不禁止警告)?
我不想更改方法的类型签名以返回Predicate<? super Animal>
或Predicate<Object>
,除非有人说服我这是正确的事情。
答案 0 :(得分:4)
Predicate<Animal> provideIsSentientPredicate()
{
return cast( Predicates.instanceOf(Human.class) );
}
static <A, B extends A> Predicate<B> cast(Predicate<A> pa)
{
@SuppressWarnings("unchecked")
Predicate<B> pb = (Predicate)(pa);
return pb;
// we know it works correctly in practice.
// or if you are a theorist, create a wrapper predicate
//
// Predicate<B>
// boolean apply(B b)
// return pa.apply(b);
}
顺便说一下,没有理由认为Guava不应该将该方法声明为
static <T> Predicate<T> instanceOf(Class<?> clazz)
与其他兄弟方法一致。