为什么Guava的ImmutableList有这么多重载的()方法?

jjn*_*guy 38 java overloading guava

我只是看着番石榴ImmutableList,我注意到这个of()方法超载了12次.

在我看来,他们所需要的只是:

static <E> ImmutableList<E> of();
static <E> ImmutableList<E> of(E element); // not even necessary
static <E> ImmutableList<E> of(E... elements);
Run Code Online (Sandbox Code Playgroud)

有这么多类似变化的原因是什么?

Col*_*inD 40

Varargs和泛型不能很好地融合在一起.Varargs方法可以使用泛型参数引发警告,并且重载会阻止该警告,除非在极少数情况下您要使用超出11个项目添加到不可变列表of().

消息来源的评论说:

这些最多可达11个.之后,您只需获得varargs表单,以及可能出现的任何警告.:(

请注意,Java 7的@SafeVarargs注释是专门添加的,以消除对此类事物的需求.可以使用of(E...)带注释的单个方法,@SafeVarargs并且不会使用泛型参数发出警告.

  • @JoãoRebelo:我的意思是对于大多数`ImmutableList.of(...)`重载,它们被实现为`construct(e1,e2,e3,e4)`等.其中`construct`被定义为`construct (对象...元素)`.所以无论如何都会分配一个数组.(我想有一些优点,比如知道传递给`construct`的数组是一个无法被调用者修改的内部数组,因此在大多数情况下你最终不需要复制该数组,但我不知道我认为特别值得关注 - 这不是创造方法的主要原因.) (3认同)
  • @JoãoRebelo:虽然......实际上并不是真的......这些方法只是立即自行调用varargs方法. (2认同)

Rin*_*nke 13

还有一个表现原因.每次调用varargs方法都会导致数组分配和初始化.如果你以某种方式确定例如95%的调用具有3个或更少的参数而只有5%具有4个或更多,那么就像这样重载

public static <E> ImmutableList<E> of();
public static <E> ImmutableList<E> of( E e );
public static <E> ImmutableList<E> of( E e1, E e2 );
public static <E> ImmutableList<E> of( E e1, E e2, E e3 );
public static <E> ImmutableList<E> of( E e1, E e2, E e3, E... es );
Run Code Online (Sandbox Code Playgroud)

在95%的案例中,性能得到了很好的提升.不同的是,平均案例表现上升.

  • 注意:虽然原理成立,但我刚从ColinD那里了解到,对于Guava来说实际上并不是这样,因为重载方法无论如何都会导致varargs调用(在当前实现中). (6认同)