Java Collection接口addAll()方法签名

时间:2011-02-15 17:16:06

标签: java generics collections

如果Java Collection Interface具有像此一样的addAll方法签名,它会有什么不同?

 <T extends E> boolean addAll(Collection<T> c);
而不是 boolean addAll(Collection<? extends E> c);

由于

-Abidi

6 个答案:

答案 0 :(得分:4)

在这种情况下,对<?>的用户来说,<T>addAll是等效的。

我认为使用前一种表示法是为了清晰起见,因为使用<T>会使addAll的签名更复杂。

答案 1 :(得分: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 :(得分:2)

问题是,T中的<T extends E> boolean addAll(Collection<T> c)完全没必要,因为addAll 并不关心 E的具体子类型给出的集合包含。所有它关心的是它给出的集合包含 E的一些子类型,这正是Collection<? extends E>的含义。

您不应该为方法引入不必要的泛型类型。

答案 3 :(得分:0)

如果您使用了显式类T,那么您无法将通配符集合传递给该方法,这是您可能希望并且应该能够执行的操作。

答案 4 :(得分:0)

基本上,当类型变量T仅用于参数类型中的某个位置时,您可以安全地将其更改为?

答案 5 :(得分:-2)

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