Java:确定函数是使用varargs还是数组调用的

有没有办法找出实际使用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:这是否有特定的名称? 它只是一个匿名数组吗?

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

 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,这应该可以帮助用户使用正确的版本。

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

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

顺便说一句:你可以做到以下几点。

 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); } 

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