-2

I had a question regarding ... parameters in java. Here is the code example

class Foo{

    private void m1(Object... params){
        //do something with params[0]
        //do something with params[1]
        //do something with params[2]
        //do something with params[3]
    }

    public void m2(Object... params){
        Object additionalParam = new Object();
        m1(additionalParam, params);
    }

}
class Example{

    public void main(String[] args){
        Foo f = new Foo();
        Object o1 = new Object();
        Object o2 = new Object();
        Object o3 = new Object();
        f.m2(o1, o2, o3);
    }
}

Does something like this work? I didn't get a compiler error, but when doing something similar, I had problems when changing the value of one of the objects from m1().


SOLUTION: I thought that the array would be flattened, but apparently that doesn't happen.

class Foo{

    private void m1(Object... params){
        //do something with params[0]
        //do something with params[1][0]
        //do something with params[1][1]
        //do something with params[1][2]
    }

    public void m2(Object... params){
        Object additionalParam = new Object();
        m1(additionalParam, params);
    }

}
class Example{

    public void main(String[] args){
        Foo f = new Foo();
        Object o1 = new Object();
        Object o2 = new Object();
        Object o3 = new Object();
        f.m2(o1, o2, o3);
    }
}

Thanks, Sibbo for your contribution.

Rik Schaaf
  • 1,101
  • 2
  • 11
  • 30
  • What is this problem? – Aleksandr Podkutin Apr 08 '15 at 13:47
  • 3
    wouldn't m2 result in an infinite regress, due to it repeatedly calling itself with an increasingly large number of arguments? – Davis Broda Apr 08 '15 at 13:47
  • What problems? Please explain more. – Maroun Apr 08 '15 at 13:48
  • m1() is private, maybe this why you were getting problems... – DAG Apr 08 '15 at 13:48
  • @DavisBroda i guess he wanted to write a method call to m1, since the m1 method wouldn´t make sense otherwise – SomeJavaGuy Apr 08 '15 at 13:49
  • 1
    Ok, for those people calling `...` as `params`, learn it's **actual** definition. It's *variable arguments* or [*varargs*](https://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html) for short. – Buhake Sindi Apr 08 '15 at 13:56
  • @BuhakeSindi I know, but parameters/arguments: same difference. The fact is: I know that Type... makes you able to pass any number of arguments (parameters) of the class Type, or pass an array of the class Type – Rik Schaaf Apr 08 '15 at 14:06
  • @fabian It is not a direct copy of the code I used, therefore I forgot the return statement: fixed – Rik Schaaf Apr 08 '15 at 14:07
  • @Coolcat, not exactly, arguments and parameters have been used in 2 different constructs, especially when referencing it using Generics Parameterized types/arguments. Don't confuse the 2. – Buhake Sindi Apr 08 '15 at 14:16
  • @BuhakeSindi [Param vs args](http://stackoverflow.com/questions/1788923/parameter-vs-argument) if this is what you mean: ok then I get that there is a difference. But that means that my use of the name params isn't wrong, since it is indeed a list of the parameters. – Rik Schaaf Apr 08 '15 at 14:26
  • @MarounMaroun I added a second program that might clarify my question more – Rik Schaaf Apr 08 '15 at 14:29

3 Answers3

1

You are passing two arguments to m1. One is an Object (A), and one an Object[] (B). To access A, you can use params[0], but to access any element i from B, you need to use params[1][i].

So if you expected that the resulting array will be flattened, no, it won't be.

If you want to change the values that are stored in the array you pass in the main method, just do it like you did in your second example. If you want to do it nicely, use proper types instead of Object.

Sibbo
  • 3,796
  • 2
  • 23
  • 41
0

The (TYPE... NAME) parameter simply says "pass in an number of objects of type TYPE". These can then be accessed regularly via NAME[x] where x is the index of the object you passed in.

EDIT: The second part of my answer was wrong. Sorry about any confusion.

Bryan Reilly
  • 114
  • 4
  • The objects are not copied. Java passes objects by reference. – Sibbo Apr 08 '15 at 13:54
  • You are wrong partially, java creates a copy that is true, but not of the object itself, it creates a copy of the reference value which in the end references the object itself. – SomeJavaGuy Apr 08 '15 at 14:10
  • @KevinEsche Does it reference the variable or does it reference its value? – Rik Schaaf Apr 08 '15 at 14:19
0

Varargs params are treated by the compiler as an Array. So your example will have to look like this:

class Foo{

    private void m1(Object... params){
        //do something
    }

    public void m2(Object... params){
        Object additionalParam = new Object();
        Object[] newArray = /* Here you need to create an array with all param elements and the new one*/
        m2(newArray);
    }

}
class Example{

    public int main(String[] args){
        Foo f = new Foo();
        Object o1 = new Object();
        Object o2 = new Object();
        Object o3 = new Object();
        f.m2(new Object[]{o1, o2, o3});
    }
}
Kelevandos
  • 7,024
  • 2
  • 29
  • 46
  • uhm, you know the difference between Object... and Object[], right? – Rik Schaaf Apr 08 '15 at 13:59
  • 1
    "Difference" is not the right word here. Varargs (the "...") allows you to pass any number of objects as the given parameter, so null, 0, one or an array. Whichever you pass, in the method code it will be treated as an array (which is aither null, empty, has only index 0 etc...) – Kelevandos Apr 08 '15 at 14:03