为什么Java中的私有成员可以从另一个类修改?

Tob*_*oby -5 java oop

在下面的示例中,即使它是类的私有成员,x也可以按类更改.这是什么原因?BA

import java.util.Date;

class A {

    private Date x;

    public A(){
        super();
        x = new Date();
    }

    public Date getDate(){
        return x;
    }

    public void print(){
        System.out.println(this.x);
    }

}

class B {

    public static void main(String[] args){
    A a = new A();

    a.print();

    Date d = a.getDate();

    d.setMonth(12);

    System.out.println(d);

    a.print();

    }

}
Run Code Online (Sandbox Code Playgroud)

输出是:

Initial date generated by A
Date changed by B
Date changed by B (why does it change a private member here?)
Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 6

private防止变量被另一个类直接访问.你不能写入d.x读或写x.

但是,如果班级选择x通过公共方法返回引用,那么它是自己选择来揭开隐私的面纱.A从允许x从getter读取或从setter修改没有任何阻止.

近年来,Java社区已经认识到了这个问题:即,如果你返回对私有可变对象的引用,你就会为你的类的内部状态打开大门,在你不知情的情况下进行混乱.为了防止这种情况,尽可能使类不可变是一种好习惯.

事实上,这Date是一个设计糟糕的可变类的完美例子.java.timeJava 8中引入的软件包添加了大量不可变的时间和日期类来替换Date.您现在可以返回私有Instant,而不用担心调用者能够更改它.

重要的是要指出不变性来自于如何定义类.这不是像语言一样的功能private.令人困惑的是,final可以用来使变量成为不可变的,但是将它应用于类并不会使类不可变(这使得它无法实现).