相关疑难解决方法(0)

何时使用通用方法以及何时使用通配符?

我正在阅读OracleDocGenericMethod中的泛型方法.当它说何时使用通配符以及何时使用通用方法时,我对比较感到非常困惑.引用文件.

interface Collection<E> {
    public boolean containsAll(Collection<?> c);
    public boolean addAll(Collection<? extends E> c);
}
Run Code Online (Sandbox Code Playgroud)

我们可以在这里使用泛型方法:

interface Collection<E> {
    public <T> boolean containsAll(Collection<T> c);
    public <T extends E> boolean addAll(Collection<T> c);
    // Hey, type variables can have bounds too!
}
Run Code Online (Sandbox Code Playgroud)

[...]这告诉我们类型参数被用于多态; 它唯一的作用是允许在不同的调用站点使用各种实际的参数类型.如果是这种情况,则应使用通配符.通配符旨在支持灵活的子类型,这是我们在此尝试表达的内容.

难道我们不认为外卡(Collection<? extends E> c);也支持那种多态?那为什么泛型方法的使用被认为不好呢?

继续向前,它说,

通用方法允许使用类型参数来表示方法和/或其返回类型的一个或多个参数的类型之间的依赖关系.如果没有这种依赖关系,则不应使用通用方法.

这是什么意思?

他们提出了这个例子

class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

[...]

我们可以用另一种方式为这种方法编写签名,而不使用通配符:

class Collections {
    public static <T, S extends …
Run Code Online (Sandbox Code Playgroud)

java generics wildcard

115
推荐指数
3
解决办法
5万
查看次数

二阶泛型似乎与一阶泛型不同

我以为我对仿制药有一个合理的把握.例如,我理解为什么

private void addString(List<? extends String> list, String s) {
    list.add(s); // does not compile
    list.add(list.get(0)); // doesn't compile either
}
Run Code Online (Sandbox Code Playgroud)

不编译.我甚至凭借这些知识获得了一些互联网业力.

但我认为这个论点不应该编译:

private void addClassWildcard(List<Class<? extends String>> list, Class<? extends String> c) {
    list.add(c);
    list.add(list.get(0));
}
Run Code Online (Sandbox Code Playgroud)

这也不应该:

private void addClass(List<Class<? extends String>> list, Class<String> c) {
    list.add(c);
    list.add(list.get(0));
}
Run Code Online (Sandbox Code Playgroud)

但两者都编译.为什么?顶部的例子有什么区别?

我很欣赏普通英语的解释,以及指向Java规范或类似部分的相关部分的指针.

java generics

18
推荐指数
2
解决办法
909
查看次数

Java泛型:通配符

因此,我正在阅读泛型,以便重新熟悉这些概念,特别是在涉及通配符的情况下,因为我几乎没有使用它们或碰到它们.从我所做的阅读中我无法理解为什么他们使用通配符.我不断遇到的一个例子如下.

void printCollection( Collection<?> c ) {
  for (Object o : c){
    System.out.println(o);
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么你不写这个:

<T> void printCollection( Collection<T> c ) {
    for(T o : c) {
        System.out.println(o);
    }
}
Run Code Online (Sandbox Code Playgroud)

来自oracle网站的另一个例子:

public static double sumOfList(List<? extends Number> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}
Run Code Online (Sandbox Code Playgroud)

为什么这不是写的

public static <T extends Number> double sumOfList(List<T> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
} …
Run Code Online (Sandbox Code Playgroud)

java generics

6
推荐指数
1
解决办法
194
查看次数

泛型.使用通配符`<?>`vs使用类型参数`<E>`

所以我通过官方的java教程,https://docs.oracle.com/javase/tutorial/java/generics/index.html,也通过stackoverflow搜索,结果发现使用<E>和之间没有太大的区别<?>,一个我可以理解的是普通的通用形式,另一个是通配符.到目前为止,我遇到的唯一区别是,当使用<E><E extetnds BlaBlaClass>我们可以引用类型时E,否则我们根本不知道有关集合或数组或类型的任何信息.

我的问题是:使用<?>(通配符)优于普通泛型是否有任何优势<E>?如果是这样,这种情况的情况是什么?为什么有人会使用通配符呢?

我看过泛型类型和通配符类型之间的区别,区别?(通配符)和Java中的Type参数,何时使用泛型方法以及何时使用通配符?,Java泛型?,E和T有什么区别?.到目前为止,它似乎<?>是较差的版本<E>

java generics wildcard

3
推荐指数
2
解决办法
969
查看次数

Java Generics:关于SO的示例说明

在另一篇SO帖子中,以下示例作为对OP的响应给出:

public static <E> void funct1(final List<E> list1, final E something)
{
    list1.add(something);
}

public static void funct2(final List<?> list, final Object something)
{
    list.add(something); // does not compile
}
Run Code Online (Sandbox Code Playgroud)

我已经验证了funct1编译,而funct2没有编译.但是,我无法弄清楚原因.

java generics

1
推荐指数
1
解决办法
49
查看次数


标签 统计

java ×6

generics ×5

wildcard ×2

future ×1