如何使用两个对象中最特殊的类型作为返回类型?

时间:2018-10-10 07:52:44

标签: java generics

我基本上想要的是,像下面的示例一样推断出更专业的类型:

Predicate<Object> first;
Predicate<String> second;

Predicate<String> firstOr = first.or(second);
Predicate<String> secondOr = second.or(first);

or(...)的方法签名将如何实现?

2 个答案:

答案 0 :(得分:4)

这可以通过以下Predicate<T>::or声明来完成:

default <R extends T> Predicate<R> or(Predicate<? super R> other) {
    return r -> this.test(r) || other.test(r);
}

这将允许or为两种Predicate类型的任何子类型创建Predicate。因此,例如,以下方法将起作用:

Predicate<Object> first;
Predicate<Number> second;

Predicate<Integer> firstOr = first.or(second);
Predicate<Integer> secondOr = second.or(first);

答案 1 :(得分:2)

我认为您需要两个重载才能起作用。但是,由于重载之间的唯一区别在于类型参数,因此它们会由于擦除而发生冲突。因此,您需要使用不同的名称(不会再使它们真正过载)。

这可能是签名:

/* In this case, the input Predicate has the most specific type.
 * Use this in the first.or(second) case
 */
public <R extends T> Predicate<R> or1(Predicate<R> pred);

/* In this case, the receiver Predicate has the most specific type.
 * Use this in the second.or(first) case
 */
public Predicate<T> or2(Predicate<? super T> pred);

如果类型参数相等(例如,如果firstsecond都具有类型Predicate<String>,则这两种方法都将工作相同)