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
不变