为什么 EnumSet 有许多重载的“of”方法?

2022-09-01 07:38:53

在浏览该方法时,我看到了多个方法的重载实现:EnumSet<E>ofof

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,但我找不到任何令人信服的解释。


答案 1

Varargs 方法创建一个数组。

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

这是有效的,因为隐式数组的创建。 是一个设计得非常非常快的类,因此通过创建所有额外的重载,他们可以在前几个情况下跳过数组创建步骤。这尤其正确,因为在许多情况下没有那么多元素,如果它们有,则可能不包含所有元素。EnumSetEnumEnumSet

Javadoc for EnumSet<E> of(E e1, E e2, E e3, E e4, E e5)

创建最初包含指定元素的枚举集。存在此方法的重载,以初始化具有一到五个元素的枚举集。提供了使用 varargs 特征的第六个重载。此重载可用于创建最初包含任意数量元素的枚举集,但可能比不使用 varargs 的重载运行速度慢。


答案 2

varags创建一个数组,那就是当我们调用

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

编译器将最后一行替换为:

x(new int[] {1});

如果我们有一个带有 1 arg 的重载方法,则不会发生这种情况:

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

然后编译器将选择第二种方法。