saltandwater
saltandwater

Reputation: 841

Passing Arrays to a method inconsistent with passing primitive data type to a method

I understand that passing an array to a method is still Pass-By-Value, however the "value" that is passed is the reference of the array. This implies that changing the contents of the array would cause the contents to get updated in an earlier frame (if it's a recursive algorithm), or when it goes back to the main method, for that matter.

import java.util.Arrays;

public class SameArrayPassedOn{
    public static void main(String[] args) {
        int[] a = {1,1,1};

        print(a);
        fun(a,0);
        print(a);
    }

    static void fun(int[] b, int count)
    {
        if(count == 1)
            return;

        b[0] = b[1] = b[2] = 2; 
        fun(b,1);
    }

    static void print(int[] a)
    {
        for(int x : a)
            System.out.print(x + " ");
        System.out.println("");
    }
}

Output 111 222

However, if you create a new array, like for example, in the code below, since the reference is changed, the updates won't be reflected when you go back to the main method.

import java.util.Arrays;

public class NewArrayCreatedAndReferencePassedOn{
    public static void main(String[] args) {
        int[] a = {1,1,1};

        print(a);
        fun(a,0);
        print(a);
    }

    static void fun(int[] b, int count)
    {
        if(count == 1)
            return;

        int[] newb = {2,2,2};
        fun(newb,1);
    }

    static void print(int[] a)
    {
        for(int x : a)
            System.out.print(x + " ");
        System.out.println("");
    }
}

Output 111 111

However, my question is, why such a design was chosen for Arrays. Why couldn't it be that, just like for a primitive data type, say, integer variable, a new int is created every time it's passed inside a function, although we are not explicitly creating a new int, or declaring one. Like for example,

import java.util.Arrays;

public class SameIntPassedOn_ButNewCopyCreatedEachFrame {
    public static void main(String[] args) {
        int i = 0;

        fun(i);
    }

    static void fun(int b)
    {
        System.out.println(b);

        if(b == 10)
            return;

        b = b+1;
        fun(b);

        System.out.println(b);
    }
}

Output

0 1 2 3 4 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1

Had the same been done for arrays, it would've allowed us to have a different copy of the array for each frame of the recursive function, which would've been very handy.

I think it would've been nice to have uniformity in behavior, because at the moment, it looks as though, to achieve the same behavior with Arrays, as is exhibited by primitive data types, such as int, float etc, when passed to a method, it is necessary to use a 'new' keyword, and create a new array before passing on to the method.

Upvotes: 1

Views: 558

Answers (3)

nhouser9
nhouser9

Reputation: 6780

However, my question is, why such a design was chosen for Arrays.

There are several main reasons.

The first is performance - it would lead to extremely poor performance if a new copy of the array had to be created every single time a method was called on it, especially for recursive calls.

Had the same been done for arrays, it would've allowed us to have a different copy of the array for each frame of the recursive function, which would've been very handy.

The second is that you already have the option of passing a copy of the array if you want to - you can create a copy manually and pass that. This way the programmer has the most control - they can choose to let method calls modify the array, or they can choose to pass a copy, allowing each method call its on version of the array to work with. If we forced the programmer to use a copy all the time, they would lose the option of letting method calls modify the array, which can be extremely useful in some situations. The current design gives the programmer the most options.

Why couldn't it be that, just like for a primitive data type...

The last reason is that an array is not a primitive data type - it is an object. The decision was most likely made to make arrays as consistent as possible with the way other objects in Java behave.

Upvotes: 3

Lew Bloch
Lew Bloch

Reputation: 3433

The answer is that all objects, in fact all method arguments are passed by value. Your assessment "Had the same been done for arrays" is wrong because the same is done for arrays. Arrays, like all object references, are passed by value. The copy of a primitive value sent to a method is the same value the caller passed. The copy of an array pointer sent to a method is the same value the caller passed. The copy of any object pointer sent to a method is the same value the caller passed. It points to the same object, because the pointer is copied by value.

Why, you ask? Because it's simple, it's valid, and really has no downside.

Upvotes: 0

Hani
Hani

Reputation: 1424

Array is a container (data structure) that hold a set of objects.

Those objects could be huge or small. and the array could contain many objects

imagine with each array reference we do full copy

the language will be extremely slow and inefficient

So the main reason for this is the efficiency

Upvotes: -1

Related Questions