[英]Why does Guava's ImmutableList have so many overloaded of() methods?
我只是看着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);
有這么多類似變化的原因是什么?
Varargs和泛型不能很好地融合在一起。 Varargs方法可以使用泛型參數引發警告,並且重載會阻止該警告,除非在極少數情況下您要使用of()
將超過11個項添加到不可變列表of()
。
消息來源的評論說:
這些最多可達11個。 之后,您只需獲得varargs表單,以及可能出現的任何警告。 :(
請注意,Java 7的@SafeVarargs注釋是專門添加的,以消除對此類事物的需求。 可以使用一個使用@SafeVarargs
注釋of(E...)
方法,並且不會使用泛型參數發出警告。
還有一個表現原因。 每次調用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 );
在95%的案例中,性能得到了很好的提升。 不同的是,平均案例表現上升。
除了這里的其他重要答案之外,還有一個微妙的運行時性能優勢(除了避免數組分配),這是零arg和單arg重載返回為表示空實例和單實例列表而優化的實現(分別)。
如果我們沒有單獨的方法重載,並且只包含一個基於varargs的方法,那么該方法看起來像這樣:
public static <E> ImmutableList<E> of(E... es) {
switch (es.length) {
case 0:
return emptyImmutableList();
case 1:
return singletonImmutableList(es[0]);
default:
return defaultImmutableList(es);
}
}
切換情況(或if-else檢查)的性能對於大多數調用來說並不是壞事,但它仍然是不必要的,因為每次優化都可能有方法重載,並且編譯器總是知道調用哪個重載。 客戶端代碼沒有任何負擔,所以這很容易獲勝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.