矛盾地转换番石榴谓词

时间:2013-04-22 16:57:05

标签: java generics guava contravariance

我有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>,除非有人说服我这是正确的事情。

1 个答案:

答案 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)

与其他兄弟方法一致。