通用vs通配符未知类型

wro*_*ame 7 java generics wildcard

什么时候建议做:

public <E> boolean hasPropertyX(List<E extends User> alist);
Run Code Online (Sandbox Code Playgroud)

public boolean hasPropertyX(List<? extends User> alist);
Run Code Online (Sandbox Code Playgroud)

看起来它们的效果也一样好.

Nay*_*uki 2

明确地将泛型类型命名为 asE和 not?具有这些用途(据我所知):

0) 将返回类型与参数类型的某些部分联系起来 - 例如:

public <E> E getSomeElement(List<E> lst) { ... }
// ^ If we don't name the argument type as having E,
// then we can't specify the return type as being E
Run Code Online (Sandbox Code Playgroud)

1) 将参数类型的某些部分与封闭类型的某些部分联系起来:

class Storage<E> {
    E item;
    public void replace(Storage<E> st) { item = st.item; }
    // ^ This wouldn't work if we wrote Storage<?> instead
}
Run Code Online (Sandbox Code Playgroud)

2) 绑定参数类型、返回类型和封闭类型的某种组合(参见 #0 和 #1)。

?如果我们不关心实际类型,我们可以使用匿名类型名称。这是一个基本示例:

boolean allEqual(List<?> lst, Object y) {
    for (Object x : lst) {  // Any reference can be stored as Object
        if (!y.equals(x))  // equals takes an Object
            return false;
    }
    return true;
}
// ^ We could also rewrite this example with List<E> and "E x".
Run Code Online (Sandbox Code Playgroud)

另一个例子:

int intSum(List<? extends Number> lst) {
    int sum = 0;
    for (Number x : lst)  // We only care that the list element is a Number
        sum += x.intValue();
    return sum;
}
// ^ We could also rewrite with List<E extends Number> and "E x".
Run Code Online (Sandbox Code Playgroud)

替代阅读:http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html