Java:找出函数是用varargs还是数组调用的

时间:2011-03-25 14:40:11

标签: java variadic-functions

有没有办法找出实际使用varargs或数组调用varargs的Java函数(或构造函数)?

说我有以下内容:

public class MyCompositeObjects {

    MyObject[] objects;

    MyCompositeObjects(MyObjects... objects) {
        this.objects = Arrays.copyOf(objects,objects.length);
        // or just: this.objects = objects; ?
    }

    // ...
}

可以使用单个MyObject[]参数调用构造函数,该参数可能稍后更改,如果我不在构造函数中复制数组,那么这些更改也将应用于成员变量objects,对?但是,如果使用多个MyObject调用构造函数,则没有其他对数组*的引用,以便稍后在类外部进行更改,因此我可以直接分配它。我可以告诉构造函数(或者,通常是任何采用varargs的函数)如何调用它?

* nb:这是否有特定的名称?它只是一个匿名数组吗?

2 个答案:

答案 0 :(得分:9)

不,你不能。这意味着完全透明 - 这段代码:

new MyCompositeObjects(a, b);

完全等同于

new MyCompositeObjects(new MyObjects[] { a, b });

如果你能信任你的调用者做正确的事情,你总是可以创建两个静态方法并使构造函数变为私有:

public static MyCompositeObjects createWithCopy(MyObjects[] values) {
    return new MyCompositeObjects(Arrays.copyOf(values, values.length));
}

public static MyCompositeObjects createWithoutCopy(MyObjects... values) {
    return new MyCompositeObjects(values);
}

private MyCompositeObjects(MyObjects[] values) {
    this.objects = values;
}

请注意“with copy”版本如何不使用varargs,这应该可以帮助用户使用正确的版本。

答案 1 :(得分:4)

唯一知道的方法是解析代码。这是因为varargs基本上是一个编译时功能,并不会改变程序的运行方式。

如果有疑问,我会一直复制数组。除非你知道这将是一个性能问题。

BTW:您可以执行以下操作。

MyCompositeObjects(MyObjects o1, MyObjects... objects) {

MyCompositeObjects(MyObjects[] objects) {

然而,这可能与您想要的相反。

另一种选择是使用静态工厂。

private MyCompositeObjects(MyObjects[] objects) {
   this.objects = objects;
}

MyCompositeObjects create(MyObjects... objects) {
    return new MyCompositeObjects(objects.close());
}

MyCompositeObjects createNotCopied(MyObjects... objects) {
    return new MyCompositeObjects(objects, false);
}

对于不太安全的版本,请使用更繁琐的方法名称。这意味着如果不经过深思熟虑地选择方法,则更有可能使用安全版本。