Is there a way to find out whether a Java function (or a constructor) that takes varargs was actually called with varargs or with an array?
Say I have the following:
No, you can't. It's meant to be entirely transparent - this code:
new MyCompositeObjects(a, b);
is exactly equivalent to
new MyCompositeObjects(new MyObjects[] { a, b });
If you can trust your callers to do the right thing, you could always create two static methods and make the constructor private:
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;
}
Note how the "with copy" version doesn't use varargs, which should help users to use the right version.
The only way to know is to parse the code. This is because varargs is basicaly a compile time feature and doesn't change how the program runs.
If in doubt, I would always copy the array. Unless you know this will be a performance issue.
BTW: You can do the following.
MyCompositeObjects(MyObjects o1, MyObjects... objects) {
MyCompositeObjects(MyObjects[] objects) {
However, this likely to do the opposite of what you want.
Another option is to use a static factory.
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);
}
Use the more cumbersome method name for the less safe version. This means if a method is chosen without much thought, the safe version is more likely to be used.