Java 这个类可以变得更不可变吗?
作为一个小优化,您可以使Java 这个类可以变得更不可变吗?,java,immutability,mutable,defensive-programming,defensive-copy,Java,Immutability,Mutable,Defensive Programming,Defensive Copy,作为一个小优化,您可以使tutees不可变,因此它甚至不能在tuteer中更改 public final class Student { private final String name; private final String course; public Student(String name, String course) { this.name = name; this.course = cour
tutees
不可变,因此它甚至不能在tuteer
中更改
public final class Student {
private final String name;
private final 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; }
}
公共导师(字符串名称,学生[]学生){
this.name=名称;
Set tuts=新的HashSet();
用于(学生:学生){
补充(学生);
}
this.tutees=Collections.unmodifiableSet(tuts);
}
公共集getTutees(){返回this.tutees;}
较短版本:
public Tutor(String name, Student[] students) {
this.name = name;
Set<Student> tuts = new HashSet<>();
for (Student student : students) {
tuts.add(student);
}
this.tutees = Collections.unmodifiableSet(tuts);
}
public Set<Student> getTutees() { return this.tutees; }
公共导师(字符串名称,学生[]学生){
this.name=名称;
this.tutees=Collections.unmodifiableSet(新HashSet(Arrays.asList(students));
}
公共集getTutees(){返回this.tutees;}
作为一个次要的优化,您可以使导师
不可变,因此它甚至不能在导师
中更改
public final class Student {
private final String name;
private final 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; }
}
公共导师(字符串名称,学生[]学生){
this.name=名称;
Set tuts=新的HashSet();
用于(学生:学生){
补充(学生);
}
this.tutees=Collections.unmodifiableSet(tuts);
}
公共集getTutees(){返回this.tutees;}
较短版本:
public Tutor(String name, Student[] students) {
this.name = name;
Set<Student> tuts = new HashSet<>();
for (Student student : students) {
tuts.add(student);
}
this.tutees = Collections.unmodifiableSet(tuts);
}
public Set<Student> getTutees() { return this.tutees; }
公共导师(字符串名称,学生[]学生){
this.name=名称;
this.tutees=Collections.unmodifiableSet(新HashSet(Arrays.asList(students));
}
公共集getTutees(){返回this.tutees;}
你的班级的不变性完全取决于学生班级的不变性。如果Student
是不可变的,那么Tutor
是不可变的,反之亦然。没有其他必要来确保Tutor
类的不变性
关于能见度。如果您的类仅在包中使用,则make是包私有的(在类级别上)。将公共方法保持为公共。您的类的不变性完全取决于
Student
类的不变性。如果Student
是不可变的,那么Tutor
是不可变的,反之亦然。没有其他必要来确保Tutor
类的不变性
关于能见度。如果您的类仅在包中使用,则make是包私有的(在类级别上)。让公共方法保持公共。是一个方便的工具包,用于在Java中生成不可变对象。如果您使用它构建整个域,它将是不可变的。它解决了“这个对象是不可变的”这个问题。是一个在Java中制作不可变对象的便捷工具包。如果您使用它构建整个域,它将是不可变的。它将“这个对象是不可变的”的问题从等式中排除。我认为您可能希望在代码审查中使用这个……如果
Student
不可变,那么代码的调用者可以稍后修改它。深度复制数组。对字符串的修改可能导致创建新字符串,您可以使用最终的StringBuffer。将某些包设为私有与不变性无关。注意:一个类要么是不可变的,要么不是--两者之间没有任何区别。如果您查看代码,那么一旦创建了Tutor对象,就无法更改其中的任何内容。但是,这并没有说明Student
对象,它仍然可以通过getTutees()
方法进行变异,如果Student
是可变的。将构造函数设为私有并实现单例模式。我认为您可能希望在代码审阅时使用此模式…如果Student
不可变,则代码的调用方可以稍后修改它。深度复制数组。对字符串的修改可能导致创建新字符串,您可以使用最终的StringBuffer。将某些包设为私有与不变性无关。注意:一个类要么是不可变的,要么不是--两者之间没有任何区别。如果您查看代码,那么一旦创建了Tutor对象,就无法更改其中的任何内容。但是,这并没有说明Student
对象,如果Student
是可变的,则仍然可以通过getTutees()
方法对其进行变异。将构造函数设为私有并实现单例模式。不变性通常被认为是一种全有或全无的现象,但可能存在灰色阴影。如果Student
实际上是不可变的。。。或有一个实施合同,在将学生[]
添加到此类后,不得保留对该学生[]的引用。。。然后,可以适当地将类视为不可变的。像Collections.unmodifiableList()这样的包装就是这样。@scottb我同意有效的不可变Student
,不知道它和我说的有什么不同。但是当Student
是可变的时,您无法确保它在通过getTutees
方法返回后不会发生突变,因为Student
实例是按原样返回的,没有包装或复制。不变性通常被认为是一种全有或全无的现象,但也可能存在灰色阴影。如果Student
实际上是不可变的。。。或有一个实施合同,在将学生[]
添加到此类后,不得保留对该学生[]的引用。。。然后,可以适当地将类视为不可变的。像Collections.unmodifiableList()这样的包装就是这样。@scottb我同意有效的不可变Student
,不知道它和我说的有什么不同。但是当Student
是可变的时,您无法确定它在通过getTutees
方法返回后是否会发生变异,因为Student
实例是按原样返回的,不包装或复制。如果在构造此对象时,Student
对象的引用保存在其他位置,并且Student
实例是可变的,则即使您编写了此类,该类仍然是可变的。既然可以回顾Student
的实现,我们就可以自信地说您的类是不可变的。没有办法真正使Tutor
不变