Java varargs分配数组对象?

时间:2011-09-17 04:49:38

标签: java variadic-functions

哇!我刚刚意识到Java中的varargs方法导致在调用它们时分配一个数组。不知道为什么我会期待任何不同的东西,但是否应该为数组提供某种池?至少对于最初的0到8个尺寸? Java中是否有任何解决方法可以使用varargs而不会为每次调用分配数组?

编辑:请理解泄漏内存到GC 只是一个不必要的开销/延迟。它是 NOT 一个像暗示的一些评论的错误。仅仅因为Java有GC并不意味着你可以随意创造大量的垃圾。

2 个答案:

答案 0 :(得分:5)

请参阅EnumSet的示例。 vararg方法

of(E first, E... rest) 

重载

of(E e1, E e2) 
of(E e1, E e2, E e3) 
of(E e1, E e2, E e3, E e4) 
of(E e1, E e2, E e3, E e4, E e5) 

如果args为5或更小,则避免创建vararg数组。 (EnumSet可能在这里走得太远了)

我认为这不是GC的关注点。创建的数组很快被解除引用,这样的年轻垃圾对GC几乎没有任何影响。

然而,实例化阵列是一项相对昂贵的操作;因为EnumSet.add()非常快,所以数组创建的开销非常明显;他们可能做了一些基准测试,并决定优化重载最多5个args。

答案 1 :(得分:2)

请记住,在现代JVM中,分配短期对象通常非常便宜。在大多数情况下,它不值得担心。

VM 可以尝试使用某种缓存,但我怀疑这样做的复杂性会超过任何好处,并且最终可能会分配更多的对象。


如果确实想要避免在紧密循环中创建varargs数组,那么没有什么可以阻止你创建自己的数组并直接传入它,如下所示:

void twiddle(String... args) { ... }

void twiddleAllData() {
    String[] args = new String[2];

    for (Data d : getData()) {
        args[0] = d.getFirst();
        args[1] = d.getSecond();
        twiddle(args);
    }
}

请注意,在此示例中,对twiddle的所有调用必须正好传递2个参数,因为这是创建的共享数组的大小。