2

I am aware that the idea of the keyword private is to enable encapsulation. However, I got confused when I realized that I can modify an Array after retrieving it with a getter, which surprised me. The same didn't work for the plain integer, although I thought java treats all variables as objects.

The example:

public class PrivContainer {
private int[] myIntArray;
private int myInt;

PrivContainer(){
    myIntArray=new int[1];
    myIntArray[0]=3;
    myInt=22;
}

public int[] getIntArray(){
    return myIntArray;
}

public int getInt(){
    return myInt;
}

public void printInt(){
    System.out.println(myIntArray[0]);
    System.out.println(myInt);
}
}


public class Main {
public static void main(String[] args){
    PrivContainer pc=new PrivContainer();
    int[] r=pc.getIntArray();
    int q=pc.getInt();
    r[0]=5;
    q=33;
    pc.printInt();
}
}

The Output of printInt() is 5,22

This means that main method could change the entries of the private array but not of the private int.

Could someone explain this phenomena to me?

Mariano
  • 6,423
  • 4
  • 31
  • 47
haedav
  • 31
  • 1
  • 4

3 Answers3

3

An array is a mutable Object. Therefore, if you have a reference to that array, you can modify its contents. You can't do the same with primitive members of a class (such as int) and with references to immutable class instances (such as String and Integer).

Your assignment :

q=33;

Would be similar to :

r = new int [5];

Both of those assignments cause the variables to contain new values, but they don't affect the state of the PrivContainer instance from which the original values of those variables were assigned.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • But the *reason* you can't do it for immutables is rather different than for primitives... – Oliver Charlesworth Oct 11 '15 at 09:12
  • @OliverCharlesworth That's partially correct. For both primitive and reference types you can't change the (primitive or reference) value of an instance member you obtain via a getter. In addition, for reference types, you can only mutate the object referred by the returned reference if it refers to a mutable class instance. – Eran Oct 11 '15 at 09:17
0

Nothing seems strange here. What happen basically as follow.

public class Main {    
    public static void main(String[] args){
        PrivContainer pc=new PrivContainer(); <-- create new `PrivContiner` object which also initialised the private variables
        int[] r=pc.getIntArray(); <-- you get the "object" integer array here and assign r to refer to that object
        int q=pc.getInt(); <-- you get the "primitive" integer here and assign q to refer the myInt variable here.
        r[0]=5; <-- you assign the first value of the array 5. Note that the object reference is still the same here
        q=33; <-- you assign the variable q to 33. Note that, this mean, the variable q refer to another primitive here (which is 33)
        pc.printInt(); <-- print the content of the object here.
    }
}

When you invoke the printInt function. the output will be 5 and 22 as the new integer (33) is assigned to q and its scope is only within the main function.

kucing_terbang
  • 4,991
  • 2
  • 22
  • 28
0

While you return an array from a getter you return the reference of that object. Since you have the reference you can change its elements. If you want to avoid this behavior you will have to return the clone of your array in that case you wont be able to change the elements of your array

public class Main {
    public static void main(String... args) {
        Arr arr = new Arr();
        int[] y = arr.getX();
        y[1] = 5;
        System.out.println(arr.getX()[1]);
    }
}

class Arr {
    private int[] x = {1, 2, 3};

    public int[] getX() {
        return x.clone();
    }
}

Try this code and remove the clone method, like this

class Arr {
    private int[] x = {1, 2, 3};

    public int[] getX() {
        return x;
    }
}

Now execute the main method, you will observe that changing value of y will change the value of array x as well.

Tom
  • 16,842
  • 17
  • 45
  • 54