dev*_*747 19 java generics bounded-wildcard unbounded-wildcard
我是Java新手.在本 文档中,他们将此作为使用通配符的用例:
static void printCollection(Collection c) {
    Iterator i = c.iterator();
    for (int k = 0; k < c.size(); k++) {
        System.out.println(i.next());
    }
}
这是他们的解决方案:
static void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}
但是我可以在没有外卡的情况下做同样的事情:
static <T> void printCollection(Collection<T> c) {
    Iterator i = c.iterator();
    for (int k = 0; k < c.size(); k++) {
        System.out.println(i.next());
    }
}
有人可以告诉我一个简单的用例,常规的泛型不起作用,但外卡会吗?
更新:此处的答案何时在Java Generics中使用通配符?不要告诉我们需要通配符.事实上,它是另一种方式.
通配符允许我们做的一件事是声明与特定类型参数无关的类型,例如“任何类型列表的列表”:
List<List<?>> listOfAnyList = ...;
listOfAnyList.add( new ArrayList<String>() );
listOfAnyList.add( new ArrayList<Double>() );
如果没有通配符:* 这是不可能的,因为元素列表可能具有彼此不同的类型。
如果我们尝试捕获它,我们会发现我们不能:
static <E> void m(List<List<E>> listOfParticularList) {}
m( listOfAnyList ); // <- this won't compile
通配符允许我们做的另一件事是类型参数不能做的事情是设置下限。(类型参数可以用绑定来声明extends,但不能用super绑定来声明。**)
class Protector {
    private String secretMessage = "abc";
    void pass(Consumer<? super String> consumer) {
        consumer.accept( secretMessage );
    }
}
假设pass改为声明采用Consumer<String>. 现在假设我们有一个Consumer<Object>:
class CollectorOfAnything implements Consumer<Object> {
    private List<Object> myCollection = new ArrayList<>();
    @Override
    public void accept(Object anything) {
        myCollection.add( anything );
    }
}
问题是:我们无法将其传递给接受 的方法Consumer<String>。声明Consumer<? super String>意味着我们可以传递任何接受String. (另请参阅Java 泛型:什么是 PECS?)
大多数时候,通配符只是让我们做出整洁的声明。
如果我们不需要使用类型,则不必为其声明类型参数。
* 技术上也可以使用原始类型,但不鼓励使用原始类型。
** 我不知道为什么 Java 不允许super使用类型参数。4.5.1. 参数化类型的类型参数可能暗示它与类型推断的限制有关:
与方法签名中声明的普通类型变量不同,使用通配符时不需要类型推断。因此,允许声明通配符的下限 [...]。
| 归档时间: | 
 | 
| 查看次数: | 347 次 | 
| 最近记录: |