Java集合接口addAll()方法签名

3
如果Java Collection接口的addAll方法签名如下,会有什么区别呢?
 <T extends E> boolean addAll(Collection<T> c);

与其使用 boolean addAll(Collection<? extends E> c); 方法,不如...

谢谢

-Abidi


3
这里编译不通过。但下面这行代码可以通过编译:<T extends E> boolean addAll(Collection<T> c); - Puce
我的错,Puce,我会去编辑它的。不过我的问题仍然存在。谢谢。 - Abidi
6个回答

4
在这种情况下,对于使用addAll的用户来说,拥有<?><T>是等效的。
我认为前一种表示法是为了清晰起见而使用的,因为使用<T>会使addAll的签名更加复杂。

2

请看这个测试接口:

public interface DumbTestInterface<E> {

    <T extends E> boolean addAll1(Collection<T> c);

    boolean addAll2(Collection<? extends E> c);

}

这里是字节码:
// Compiled from DumbTestInterface.java (version 1.6 : 50.0, no super bit)
// Signature: <E:Ljava/lang/Object;>Ljava/lang/Object;
public abstract interface rumba.dumba.DumbTestInterface {

  // Method descriptor #6 (Ljava/util/Collection;)Z
  // Signature: <T:TE;>(Ljava/util/Collection<TT;>;)Z
  public abstract boolean addAll1(java.util.Collection arg0);

  // Method descriptor #6 (Ljava/util/Collection;)Z
  // Signature: (Ljava/util/Collection<+TE;>;)Z
  public abstract boolean addAll2(java.util.Collection arg0);
}

正如您所看到的,生成的字节码没有任何区别(除了生成的调试代码)。因此,如果这两个版本是等效的,您可能会选择使用更容易理解的版本。


2
事实上,在<T extends E> boolean addAll(Collection<T> c)中,T是完全不必要的,因为addAll并不关心给定的集合包含了哪个具体的E子类型。它只关心给定的集合包含了E的某个子类型,这正是Collection<? extends E>的意义所在。
你不应该在方法中引入不必要的泛型类型。

0
如果您使用了显式类T,那么您将无法将通配符集合传递给该方法,而这可能是您想要做的事情,并且应该能够实现。

0

基本上,当类型变量 T 只会在参数类型的某个地方使用一次时,您可以安全地将其更改为 ?


-2

我认为这不会编译。一个方法不能同时具有两种返回类型(<T>boolean)。


7
<T>不是一个返回类型,而是一个通用类型。 - Adam Paynter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接