在Java中欺骗私有关键字

时间:2015-10-11 09:08:03

标签: java object reference encapsulation getter

我知道关键字private的想法是启用封装。但是,当我意识到我可以在使用getter检索数组后修改数组时,我感到很困惑,这让我感到惊讶。虽然我认为java将所有变量视为对象,但同样没有对普通整数起作用。

示例:

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();
}
}

printInt()的输出为5,22

这意味着main方法可以更改私有array的条目,但不能更改私有int的条目。

有人可以向我解释这个现象吗?

3 个答案:

答案 0 :(得分:3)

数组是一个可变对象。因此,如果您有对该数组的引用,则可以修改其内容。您不能对类的基本成员(例如int)和对不可变类实例的引用(例如StringInteger)执行相同的操作。

你的任务:

q=33;

类似于:

r = new int [5];

这两个赋值都会导致变量包含新值,但它们不会影响PrivContainer实例的状态,从中可以分配这些变量的原始值。

答案 1 :(得分:0)

这里似乎没什么奇怪的。基本上发生了什么。

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.
    }
}

调用printInt函数时。输出将为5和22,因为新的整数(33)已分配给q,其范围仅在main函数内。

答案 2 :(得分:0)

从getter返回数组时,返回该对象的引用。由于您有参考,您可以更改其元素。如果你想避免这种行为,你将不得不返回你的数组的克隆,在这种情况下,你将无法更改数组的元素

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();
    }
}

尝试此代码并删除克隆方法,如此

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

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

现在执行main方法,您会发现更改y的值也会更改数组x的值。