简单的通配符使用误区

simple wildcard use missunderstanding

我在看通配符,我以一种非常简单的方式理解了它们。 <? extends Type> 当我仅将它们用于读取时 (Returntype) 和 <? super Type> 当我将其用于写入时 (Parametertype)

interface P<T> {
    boolean eval(T e);
}

public class IsZero implements P<Integer> {
    public boolean eval(Integer e) {
        return e.intValue() == 0;
    }
}

public class QQ<T> {
    public void filter(Q<T> q1, Q<T> q2, P<T> p) {
        while (!q2.isEmpty()) {
            T tmp = q2.remove();
            if (p.eval(tmp)) {
                q1.add(tmp);
            }
        }
    }
}

所以,给出了这个代码。我的教授写了以下解决方案:

/*
Q<? super T> q1 just used as a Parametertype for writing (add)
Q<? extends T> q2 just used as a Returntype for reading (remove)
P<? super T> p just used as Parametertype (eval)
*/

我同意这一点,但我无法弄清楚为什么它是 P<? super T> 因为 eval returns 是一个布尔值?还是我把整个 Return/Parameter 都弄错了?

p 和 q1 需要是 Q<? super T> 出于同样的原因......因为两者都需要能够 handle T 的任何实例并且如果你能够处理 T 或其任何 super类 你在这方面做得很好。所以将它设置为 Q<? super T> 而不是 Q<T> 的原因是使您的代码尽可能通用。

另一种表达方式...如果X > Y 表示X 是Y 的superclass/interface 或Y 本身并且p 是Q<A> , q1 为 Q<B> 且 q2 为 Q<C>

上面的约束声明A > CB > C不管AB之间的关系是什么;如果其中至少一个是接口,则它们可能根本不相关。

方法调用是否要修改主题都没有关系。

顺便说一句,在大多数 Java 标准集合中 类 add 也是一个布尔值,用于指示操作是否更改了大部分时间被忽略的集合.所以这根本不相关。