2

Assuming we have a method that receives at least one parameter and potentially 0 or more parameters of the same type:

public void method(T p1, T... otherPs)

And that we have a method that calls it that looks like this:

public void callingMethod(T... params) 

that we know has at least one parameter.

Is it possible to call method from callingMethod to look something like this?

public void callingMethod(T... params){
    [...]
    method(params[0], restOfParams);
    [...]
}
CosminO
  • 5,018
  • 6
  • 28
  • 50
  • not really, you would need to use `Arrays::copyOfRange` looks like in this case – Eugene Apr 05 '19 at 09:20
  • You can change signature of the method to accept second parameter as a list of Type. And use that list to retrieve values. List can hold values 0...n . – Abhishek Tiwari Apr 05 '19 at 09:21
  • the signature of the 'method' cannot be changed, only the 'callingMethod'. Number of parameters is not known, it is built during runtime, so the only thing I know is that there will be at least one. Also, creating new array would potentially cause issues as to resource management. Also#2: creating new method on top is not permitted, due to the same reasons. – CosminO Apr 05 '19 at 09:58

3 Answers3

4

Sure, that is possible and pretty easy.
The only overhead is the creation of another array.
See Eugene answer to understand the memory consumption.


public void callingMethod(T... params){
    ...
    method(params[0], Arrays.copyOfRange(params, 1, params.length));
    ...
}

A bit off topic, but I just run JOL, as suggested, and here is the output for an empty references' array

final String[] array = new String[0];

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 0x0000000800000000 base address and 0-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

[Ljava.lang.String;@7ea37dbfd object externals:
          ADDRESS       SIZE TYPE                PATH                           VALUE
        71695b2d0         16 [Ljava.lang.String;                                []

For an array with a single, null, element

final String array = new String[1];

[Ljava.lang.String;@7ea37dbfd object externals:
          ADDRESS       SIZE TYPE                PATH                           VALUE
        71692a7a8         24 [Ljava.lang.String;                                [null]

For an array containing a single, non-null, element

final String array = new String[1];
array[0] = new String("");

[Ljava.lang.String;@7ea37dbfd object externals:
          ADDRESS       SIZE TYPE                PATH                           VALUE
        707612b68         16 [B                  [0].value                      []
        707612b78    1577856 (something else)    (somewhere else)               (something else)
        707793ef8         24 [Ljava.lang.String;                                [(object)]
        707793f10         24 java.lang.String    [0]                            (object)
LppEdd
  • 20,274
  • 11
  • 84
  • 139
  • _only_ another array reference? that is created a whole new array. – Eugene Apr 05 '19 at 09:23
  • @Eugene if the elements are references, their pointers are simply copied. – LppEdd Apr 05 '19 at 09:23
  • an array has at least two headers + the size, and those references have at least `12 bytes` each too – Eugene Apr 05 '19 at 09:24
  • that is a wrong calculation. I recommend you use `jol` for this to know exactly what it is - or simply don't put it in the answer if you are not sure or guess (it's not related to the question anyway) – Eugene Apr 05 '19 at 09:31
  • I'll give `jol` a try, but I'm pretty sure the calculation is right. – LppEdd Apr 05 '19 at 09:33
  • at least the fact that you say that array elements references are `8 bytes` *is* wrong. each object has two headers, either they have `12` or `16` bytes total; then `array reference` is usually `12` bytes too with compressed OOP; then the padding is also at least miss-placed in your answer. read more [here](https://stackoverflow.com/a/47749301/1059372) – Eugene Apr 05 '19 at 09:38
  • @Eugene thanks, that is interesting, I removed the bytes counts. Will eventually link your answer. – LppEdd Apr 05 '19 at 09:45
  • @Eugene could you check out the results I got from JOL? – LppEdd Apr 05 '19 at 10:11
  • @Eugene it seems the array size per-se is 16 bytes, plus 8 per reference to a `String`. – LppEdd Apr 05 '19 at 10:40
  • sorry, have no time to deal with this now - did you check the JOL samples? there are thins that are explained there IIRC – Eugene Apr 05 '19 at 10:43
  • @Eugene yes, that's straight from the samples. No worries – LppEdd Apr 05 '19 at 10:43
3

Yes, in a least a couple of ways.

Because varargs in Java is syntactic sugar around passing in an array, yu can create an array with the rest of the params (perhaps using Arrays.copyOfRange) and pass that in as the second argument:

method(params[0], Arrays.copyOfRange(params, 1, params.length));

The other way is via reflection, but you don't need that here.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
-1

I don't understand your question, but not necessary that there is at least one parameter in varargs.

Additionally, you can check params.length != 0

And then call method(params[0], Arrays.copyOfRange(params, 1, params.length));

Akshay Misal
  • 683
  • 6
  • 6