gpt4 book ai didi

Java,使类不可变

转载 作者:行者123 更新时间:2023-12-03 02:27:24 26 4
gpt4 key购买 nike

我在网上发现了这个练习,其中我有两个类,我应该使 Tutor 类不可变。但是,我唯一能想到的就是将 final 添加到 name 字段。当谈到构造函数时,我认为我不需要更改 name 变量的初始化,因为 String 是不可变的。我不确定如何处理集合以及如何使构造函数的这一部分不可变。 根据练习,我不应该更改 Student 类(我可以看到它是可变的)

public class Student {    
private String name;
private String course;

public Student(String name, String course) {
this.name = name;
this.course = course;
}

public String getName() {
return name;
}

public String getCourse() {
return course;
}

public void setName(String name) {
this.name = name;
}

public void setCourse(String course) {
this.course = course;
}
}

public final class Tutor {
private String name;
private final Set<Student> tutees;

public Tutor(String name, Student[] students) {
this.name = name;
tutees = new HashSet<Student>();
for (int i = 0; i < students.length; i++)
tutees.add(students[i]);
}

public Set<Student> getTutees() {
return Collections.unmodifiableSet(tutees);
}

public String getName() {
return name;
}
}

最佳答案

Tutor类呈现出许多促进其不变性的方面:

  • 类(class)已结束
  • Set<Student>受到保护以防止修改
  • 没有方法允许直接更改类的状态

但是,构造函数的防御性副本并不完整。
它还必须复制 Student s 传递的数组元素。否则,构造函数的客户端可能会更改它们的任何实例,并使 Tutor实例可变,例如:

Student[] students = ...;
Tutor tutor = new Tutor(name, students);
students[0].setName("new Name!"); // break the immutability of Tutor

你应该写这样的内容:

public Tutor(String name, Student[] students){
this.name = name;
tutees = new HashSet<Student>();
for (Student student : students){
Student copy = new Student(student.getName(),
student.getCourse());
tutees.add(copy);
}
}

另外请注意 Set返回者 getTutees()不可修改,但其中包含的元素为 Student是可变的。因此,为了使 Tutor 不可变,您还必须在返回 getTutees() 时创建 Student 元素的副本。例如:

public Set<Student> getTutees(){
Set<Student> students = new HashSet<>();
for (Student student : tutees){
Student copy = new Student(student.getName(),
student.getCourse());
students.add(copy);
}
return Collections.unmodifiableSet(students);
}

正如您可能注意到的,在这些条件下获得不变性(我们希望不可变的实例,但包含引用可变实例的集合)需要编写更多代码(用于读取/维护/测试)并执行更多处理(执行速度较慢)。
如果Student是一个不可变的类,原来的getTutees()原来的构造函数就足够了。

关于Java,使类不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50257305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com