简单的通配符使用误解

时间:2017-03-29 13:59:54

标签: java generics wildcard

我正在看通配符,我以非常简单的方式理解它们。 <? extends Type>当我使用它们只是为了阅读(返回类型)和<? 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返回一个布尔值?或者我得到整个返回/参数的东西错了?

1 个答案:

答案 0 :(得分:0)

出于同样的原因,p和q1需要Q<? super T> ...因为两者都需要能够处理 T的任何实例,如果你能够处理T或任何在这方面你很擅长超级班。因此,将其设置为Q<? super T>而不是Q<T>的原因是为了使您的代码尽可能通用。

另一种表达方式......如果X > Y表示X是YY本身的超类/接口且p为Q<A>,则q1为{ {1}}和q2是Q<B>

上述约束表明Q<C>A > C无论B > CA之间的关系是什么;如果它们中至少有一个是接口,则可能根本不相关。

方法调用是要修改还是不修改主题无关紧要。

顺便提一下,在大多数Java标准集合中,类B也返回一个布尔值来指示操作是否更改了大部分时间忽略的集合。所以这根本不相关。