Java中的上界通配符

时间:2018-06-30 08:46:09

标签: java generics bounded-wildcard

我有两个通用方法来计算List的元素之和。这些方法的签名是

  1. double method1(List<? extends Number> list)-在这里我使用通配符。

  2. <U extends Number> double sumOfList1(List<U> list)-这是类型参数的名称。

这两者之间是否存在区别,或者在功能方面相同?使用类型参数名称代替通配符有什么优势?

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

 public static <U extends Number> double sumOfList1(List<U> list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

谢谢。

3 个答案:

答案 0 :(得分:3)

绝对没有区别,声明if ($threads == 1) { for my $id (0 .. $nbInputFiles) { $self->{$id}->{_currentFile} = $self->{inputFiles}[$id] ; $self->readBamInputFile($id) ; $self->correctMatrice($id) ; print STDERR "INFO $prog $datestring: $self->{$id}->{_currentFile} -> correcting matrice done !\n" ; } } else { my $pm = new Parallel::ForkManager($threads); $pm->set_waitpid_blocking_sleep(0); $pm->run_on_finish(sub { my ($pid, $exit, $id, $signal, $core, $data) = @_; $self->{$id}->{cov} = $data->{ret}->{$id}->{cov} ; $self->{$id}->{_currentSample} = $data->{ret}->{$id}->{_currentSample} ; $self->correctMatrice($id) ; print STDERR "INFO $prog $datestring: $data->{ret}->{$id}->{_currentFile} -> correcting matrice done !\n" ; $ret[$id] = delete $data->{ret}; $err[$id] = delete $data->{err}; }); for my $id (0 .. $nbInputFiles) { $self->{$id}->{_currentFile} = $self->{inputFiles}[$id] ; $pm->start($id) and next; # here do the child # my $res = eval { $task[0]->($self) }; my $res = eval { &readBamInputFile($self, $id) }; $pm->finish(0, { ret => $self, err => $@ }); } $pm->wait_all_children; } 的目的是让您可以使用它:

U

这意味着您不在乎 public static <U extends Number> void doSomething(List<U> list, Consumer<U> sink) { list.forEach(sink::accept) } 是什么,但它必须从U开始。您需要关心的是Number包含的类型与List可以接受的类型兼容。


或者,您可以在方法内部使用Consumer来声明泛型的新实例:

U

是的,我知道,有更巧妙的方法可以做到这一点-请把它当作一个说明性示例

答案 1 :(得分:1)

由于您没有在此方法中使用public interface Eatable { void eat(); } ,因此它们没有区别。

答案 2 :(得分:0)

由于类型擦除,最后执行的代码是相同的,因此使用彼此之间没有区别。

类型擦除的说明in this site如下:

  

仅在编译时强制执行类型约束的过程,   在运行时丢弃元素类型信息。