在下面的示例中,即使它是类的私有成员,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)
private防止变量被另一个类直接访问.你不能写入d.x读或写x.
但是,如果班级选择x通过公共方法返回引用,那么它是自己选择来揭开隐私的面纱.A从允许x从getter读取或从setter修改没有任何阻止.
近年来,Java社区已经认识到了这个问题:即,如果你返回对私有可变对象的引用,你就会为你的类的内部状态打开大门,在你不知情的情况下进行混乱.为了防止这种情况,尽可能使类不可变是一种好习惯.
事实上,这Date是一个设计糟糕的可变类的完美例子.java.timeJava 8中引入的软件包添加了大量不可变的时间和日期类来替换Date.您现在可以返回私有Instant,而不用担心调用者能够更改它.
重要的是要指出不变性来自于如何定义类.这不是像语言一样的功能private.令人困惑的是,final可以用来使变量成为不可变的,但是将它应用于类并不会使类不可变(这使得它无法实现).