0

From what I know, local vars and args are stored in the Stack Memory, which includes object references, whereas actual objects are stored in the heap memory. So what exactly happens when you use var-args ?

public static int[] test(int... x) {
    return x;
}

public static void main(String[] args) {
    int[] a = test(1,2,3,4,5);
    int[] b = test(6,7,8,9,0);
    System.out.println(a);
    System.out.println(b);
    for (int i : a) {
        System.out.println(i);
    }
    for (int i : b) {
        System.out.println(i);
    }

Here I believe that all the values passed as params to test in x are stored on the stack, hence when we call test(1,2,3,4,5), we are using up stack space, correspondingly when we call test(6,7,8,9,0) we should be causing memory collision on the stack... but when I run the above, I get the following result.

[I@2db0f6b2
[I@3cd1f1c8
1
2
3
4
5
6
7
8
9
0

As can be seen, there is no corruption of items in a due to the 2nd call to test which generates b. Both seem to be stored differently.

Does this mean that the params are somehow stored on the heap? Would this mean that any call of the form function(param) translates to the value of param (primitive or memory reference) not necessarily lying on the stack memory?

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Codi
  • 511
  • 3
  • 19
  • 4
    varargs are syntactic sugar for passing an array as argument. So it works the same way as `test(new int[] {1, 2, 3, 4, 5})`. https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html#varargs – JB Nizet Aug 03 '18 at 12:37
  • Thanks for the doc! – Codi Aug 03 '18 at 12:45
  • 1
    almost whatever thing related to Java can be explained by googling "java tutorial", and looking in the 5 first hits for the official Oracle Java tutorial. The amount of time you spare when you can use google is amazing. That's what I did to find this tutorial. I simply googled for "Java varargs tutorial" – JB Nizet Aug 03 '18 at 12:50
  • I was confused about this because [Baeldung](https://www.baeldung.com/java-varargs#2-escaping-varargs-reference) mentioned that it was bad to let the varargs array escape the method, but then the JDK did it in the `Arrays.asList` implementation. It took me a while to find something that explained this beyond a few simple examples. – DBear Apr 21 '22 at 01:46
  • That's the reason the "@SafeVarargs" annotation was introduced in Java 9, where u can specify that we aren't messing things up. The main problem comes when you use generics, since Java would do Type Erasure and everything would basically be of type "Object" or the base container. Hence things work at compile time (Java would auto cast from Object to your Genetic type) but fails at runtime with an ClassCastException – Codi Apr 21 '22 at 03:17
  • Without generics there usually aren't too many problems. "Arrays.asList" is also marked as SafeVarargs as it does not really try to access the data. It just gives u back what u give it, wrapped in List wrapper. So can ClassCastExecptions happen here ? Absolutely yes, but not inside the JDK code. If something does go wrong, then it's you who did it, but again, it's not easy to reach this scenario if you're properly typing your variables (no raw types, etc) as the compiler would ensure type correctness. – Codi Apr 21 '22 at 03:29

2 Answers2

6

Varags are just a syntactic sugaring on top of arrays - i.e., using a int... parameter is the same as an int[]. Like all arrays, the array resides on the heap, and you pass a reference to it down on the stack.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

x... is only a syntactic sugar for a x[]. Think its working procedure exactly same as raw array.

The reference itself could be stored on the heap if it is a member of a class or object, or on the stack if it is a local variable in a method. And primitive types can be stored on the heap if they are members of a class or object. - Source