内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
我的目标是使一个Java对象不可变。我有一堂课Student
。我通过以下方式对其进行编码以实现不变性:
public final class Student {
private String name;
private String age;
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
我的问题是,为这个Student
班级实现不变性的最好方法是什么?
你的课堂严格来说并非不可变的,它只是有效的不可变的。为了使其不可变,您需要使用final
:
private final String name;
private final String age;
尽管差异可能看起来很微妙,但它可以在多线程环境中产生显着差异。一个不可变的类本质上是线程安全的,一个有效的不可变类只有在它被安全地发布时才是线程安全的。
有几件事你必须考虑做一个不可变的类:
final
- 你已经拥有了private
并final
在代码中进行适当的更改List
,或者Date
使它们final
不够用。你应该从它们中返回一个防御副本getters
,这样他们的状态就不会被调用方法所改变。对于第四点,假设你Date
在你的课堂中有一个领域,那么该领域的吸气剂应该看起来像:
public Date getDate() {
return new Date(this.date.getTime());
}
当你的可变字段本身包含一些可变字段,并且可以包含一些其他可变字段时,制作防御副本可能会变得头痛。在这种情况下,你需要迭代地复制它们中的每一个。我们将这个可变字段的迭代副本命名为Deep Copy。
自己实施深层复制可能会很麻烦。但是,将这个问题分开后,一旦发现自己已经陷入了进行深度防御复制的要求,就应该重新考虑自己的班级设计。