34

メソッドを調べている間、EnumSet<E> ofメソッドの複数のオーバーロードされた実装を見てきましたof

public static <E extends Enum<E>> EnumSet<E> of(E e)

public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2)

.
.

public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)

そして、別のオーバーロードされたメソッドvarargs

public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
    EnumSet<E> result = noneOf(first.getDeclaringClass());
    result.add(first);
    for (E e : rest)
        result.add(e);
    return result;
}

この varargs が他の実装を処理できたのに、なぜこのメソッドがこのようにオーバーロードされるのでしょうか? これには具体的な理由はありますか?

同じJavadocを調べましたが、説得力のある説明が見つかりませんでした。

4

4 に答える 4

29

Varargs メソッドは配列を作成します。

public static void foo(Object... args) {
  System.out.println(args.length);
}

暗黙的な配列の作成により、これは機能します。EnumSet非常に高速になるように設計されたクラスであるため、余分なオーバーロードをすべて作成することで、最初のいくつかのケースで配列の作成手順をスキップできます。Enum多くの場合、それほど多くの要素がないため、これは特に当てはまりEnumSetます。

の JavadocEnumSet<E> of(E e1, E e2, E e3, E e4, E e5) :

指定された要素を最初に含む列挙セットを作成します。このメソッドのオーバーロードは、1 ~ 5 個の要素で列挙セットを初期化するために存在します。varargs 機能を使用する 6 番目のオーバーロードが提供されます。このオーバーロードは、最初に任意の数の要素を含む列挙セットを作成するために使用できますが、varargs を使用しないオーバーロードよりも実行が遅くなる可能性があります。

于 2015-08-10T16:13:05.887 に答える
8

varags は配列を作成します。

void x(int...x) {...}
..
x(1);

コンパイラは最後の行を次のように置き換えます。

x(new int[] {1});

引数が 1 つのオーバーロードされたメソッドがある場合は発生しません。

void x(int...x) {...}
void x(int x) {...}

次に、コンパイラは 2 番目の方法を選択します。

于 2015-08-10T16:15:03.073 に答える
7

そのクラスは Josh Bloch によって設計されたものであり、彼は物事がどのように機能するかを知っています。:) 配列の作成に加えて、varargs メソッドにはループが含まれています。これは、JIT がコードを最適化するためのより多くの作業です。

たとえば、5 つのパラメーターを持つオーバーロードされたバージョンの実装を見ると、次のようになります。

result.add(e1);
result.add(e2);
result.add(e3);
result.add(e4);
result.add(e5);

次のような、すでに展開されたループのようなものであることがわかります。

for (E e : Arrays.asList(e1, e2, e3, e4, e5)) {
   result.add(e);
}

また、短くて単純なメソッドは、長くて複雑なメソッドよりもインライン化される可能性が高くなります。

于 2015-08-10T17:31:42.590 に答える
6

javadocから:

このメソッドのオーバーロードは、1 ~ 5 個の要素で列挙セットを初期化するために存在します。varargs 機能を使用する 6 番目のオーバーロードが提供されます。このオーバーロードは、最初に任意の数の要素を含む列挙セットを作成するために使用できますが、varargs を使用しないオーバーロードよりも実行が遅くなる可能性があります。

于 2015-08-10T16:13:14.540 に答える