创建不可变的Java对象

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (18)

我的目标是使一个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;

尽管差异可能看起来很微妙,但它可以在多线程环境中产生显着差异。一个不可变的类本质上是线程安全的,一个有效的不可变类只有在它被安全地发布时才是线程安全的。

用户回答回答于

有几件事你必须考虑做一个不可变的类:

  • 让你的classfinal- 你已经拥有了
  • 制作所有字段privatefinal在代码中进行适当的更改
  • 不要提供任何改变实例状态的方法
  • 如果你的班级中有可变字段List,或者Date使它们final不够用。你应该从它们中返回一个防御副本getters,这样他们的状态就不会被调用方法所改变。

对于第四点,假设你Date在你的课堂中有一个领域,那么该领域的吸气剂应该看起来像:

public Date getDate() {
    return new Date(this.date.getTime());
}

当你的可变字段本身包含一些可变字段,并且可以包含一些其他可变字段时,制作防御副本可能会变得头痛。在这种情况下,你需要迭代地复制它们中的每一个。我们将这个可变字段的迭代副本命名为Deep Copy

自己实施深层复制可能会很麻烦。但是,将这个问题分开后,一旦发现自己已经陷入了进行深度防御复制的要求,就应该重新考虑自己的班级设计。

扫码关注云+社区