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

时间:2022-11-15 00:05:04

While going through the EnumSet<E> of method, I have seen multiple overloaded implementations of of method:

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

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)

and then another overloaded method with varargs

然后使用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;
}

When this varargs could have handled the other implementations, why this method is overloaded this way? Is there any specific reason for this?

当这个varargs可以处理其他实现时,为什么这个方法会以这种方式重载?这有什么具体原因吗?

I had gone through the Javadoc of the same, but I could not find any convincing explanation.

我曾经历过同样的Javadoc,但我找不到任何令人信服的解释。

4 个解决方案

#1


30  

Varargs methods create an array.

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

This works, because of the implicit array creation. EnumSet is a class designed to be very, very fast, so by creating all the extra overloads they can skip the array creation step in the first few cases. This is especially true since in many cases Enum don't have that many elements, and if they do, the EnumSet might not contain all of them.

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

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

EnavSet的Javadoc (E e1,E e2,E e3,E e4,E e5):

Creates an enum set initially containing the specified elements. Overloadings of this method exist to initialize an enum set with one through five elements. A sixth overloading is provided that uses the varargs feature. This overloading may be used to create an enum set initially containing an arbitrary number of elements, but is likely to run slower than the overloadings that do not use varargs.

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

#2


8  

varags creates an array, that is when we call

varags创建一个数组,就在我们打电话的时候

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

Compiler replaces last line with this:

编译器用以下代码替换最后一行:

x(new int[] {1});

It will not happen if we have an overloaded method with 1 arg:

如果我们有一个带有1个arg的重载方法,它将不会发生:

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

Then compiler will choose the second method.

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

#3


7  

Because that class was designed by Josh Bloch, and that guy knows how things work. :) Besides creating an array, the varargs method contains the loop, which is more work for the JIT to optimize the code.

因为那个班级是由Josh Bloch设计的,那个人知道事情是如何运作的。 :)除了创建一个数组之外,varargs方法还包含循环,这对JIT来说更有效,可以优化代码。

For example, if we look at the implementation of the overloaded version with five parameters:

例如,如果我们查看带有五个参数的重载版本的实现:

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

we notice that it is some kind of an already unrolled loop that could look like:

我们注意到它是某种已经展开的循环,看起来像:

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

Also, shorter and simpler methods are more likely to be inlined than longer and more complex ones.

此外,更短更简单的方法更可能被内联,而不是更长和更复杂的方法。

#4


6  

From the javadoc:

来自javadoc:

Overloadings of this method exist to initialize an enum set with one through five elements. A sixth overloading is provided that uses the varargs feature. This overloading may be used to create an enum set initially containing an arbitrary number of elements, but is likely to run slower than the overloadings that do not use varargs.

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

#1


30  

Varargs methods create an array.

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

This works, because of the implicit array creation. EnumSet is a class designed to be very, very fast, so by creating all the extra overloads they can skip the array creation step in the first few cases. This is especially true since in many cases Enum don't have that many elements, and if they do, the EnumSet might not contain all of them.

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

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

EnavSet的Javadoc (E e1,E e2,E e3,E e4,E e5):

Creates an enum set initially containing the specified elements. Overloadings of this method exist to initialize an enum set with one through five elements. A sixth overloading is provided that uses the varargs feature. This overloading may be used to create an enum set initially containing an arbitrary number of elements, but is likely to run slower than the overloadings that do not use varargs.

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

#2


8  

varags creates an array, that is when we call

varags创建一个数组,就在我们打电话的时候

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

Compiler replaces last line with this:

编译器用以下代码替换最后一行:

x(new int[] {1});

It will not happen if we have an overloaded method with 1 arg:

如果我们有一个带有1个arg的重载方法,它将不会发生:

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

Then compiler will choose the second method.

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

#3


7  

Because that class was designed by Josh Bloch, and that guy knows how things work. :) Besides creating an array, the varargs method contains the loop, which is more work for the JIT to optimize the code.

因为那个班级是由Josh Bloch设计的,那个人知道事情是如何运作的。 :)除了创建一个数组之外,varargs方法还包含循环,这对JIT来说更有效,可以优化代码。

For example, if we look at the implementation of the overloaded version with five parameters:

例如,如果我们查看带有五个参数的重载版本的实现:

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

we notice that it is some kind of an already unrolled loop that could look like:

我们注意到它是某种已经展开的循环,看起来像:

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

Also, shorter and simpler methods are more likely to be inlined than longer and more complex ones.

此外,更短更简单的方法更可能被内联,而不是更长和更复杂的方法。

#4


6  

From the javadoc:

来自javadoc:

Overloadings of this method exist to initialize an enum set with one through five elements. A sixth overloading is provided that uses the varargs feature. This overloading may be used to create an enum set initially containing an arbitrary number of elements, but is likely to run slower than the overloadings that do not use varargs.

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