Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how is Array object different from other objects

Tags:

java

I am confused by the way arrays work. If I pass an array reference to some method, then that method is able to change the index values previously stored in array. However, if do the same with, say, a wrapper class object then that method is not able to change the value. Here is the code:

public class TestArray {
    public static void main(String[] args) {
        ChangeValues ch=new ChangeValues();
        int intArr[]={1,2,3};
        Integer iWrapper=new Integer(123);
        ch.changeArray(intArr);
        for(int i:intArr){
            System.out.print(i);// o/p: 789
        }
        System.out.println("\n-----------------");
        ch.changeWrapper(iWrapper);
        System.out.println(iWrapper);// o/p: 123
    }
}

class ChangeValues{
    void changeArray(int i[]){
        i[0]=7;
        i[1]=8;
        i[2]=9;
    }
    void changeWrapper(Integer i){
        i=789;
    }
}

output:

789
-----------------
123

Why is it that an array is able to change and not wrapper object. can any one clear away my doubts? thanks.

like image 792
JPG Avatar asked Jun 09 '26 17:06

JPG


2 Answers

All arguments to Java methods are passed by value. When the argument is of a reference type (as opposed to a primitive type) then the reference is passed by value. Essentially, that means the method receives a copy of the caller's value.

Any reference to a mutable object may be used to modify that object, but that's different from modifying the variable holding the reference. The two change methods you provided are unlike in that way: changeArray() modifies the array object to which its argument refers, but changeWrapper() only assigns a new value to the local variable (initially) containing its argument.

like image 53
John Bollinger Avatar answered Jun 11 '26 11:06

John Bollinger


Because the wrapper objects are immutable. You have to create a new instance, and since you can't modify a caller's reference you can't modify the wrapper instance. You could (if using Java 8) use an Optional, or create your own POJO and pass it (as long as you modify the POJO's reference, then a caller can access it from the POJO). Something like,

class POJO<T> {
    T v;

    public POJO(T v) {
        this.v = v;
    }

    public T getValue() {
        return v;
    }

    public void setValue(T v) {
        this.v = v;
    }

    @Override
    public String toString() {
        return String.valueOf(v);
    }
}

public static void changeIt(POJO<Integer> a) {
    a.setValue(123);
}

public static void main(String args[]) throws Exception {
    POJO<Integer> p = new POJO<>(1);
    System.out.println(p);
    changeIt(p);
    System.out.println(p);
}

Output is

1
123
like image 42
Elliott Frisch Avatar answered Jun 11 '26 11:06

Elliott Frisch