Java 作为成员变量的不可变类中的对象
我有一个类X,它保存Employee对象。我想使类X不可变。现在,即使我将Employee对象声明为final,Employee类也独立存在,人们可以访问特定Employee对象的setter方法。是否可能有一个普通的类Employee和另一个不可变的类X,其中包含Employee,但一旦分配了Employee,我们就不能更改它的值Java 作为成员变量的不可变类中的对象,java,immutability,Java,Immutability,我有一个类X,它保存Employee对象。我想使类X不可变。现在,即使我将Employee对象声明为final,Employee类也独立存在,人们可以访问特定Employee对象的setter方法。是否可能有一个普通的类Employee和另一个不可变的类X,其中包含Employee,但一旦分配了Employee,我们就不能更改它的值 public final class X { private final Employee emp; public X (Employee e){ thi
public final class X {
private final Employee emp;
public X (Employee e){
this.emp = e;
}
public Employee getEmp(){
return emp;
}
}
employee类我不想使其不可变,只想使类X不可变。因此,一旦员工被分配,就不应该允许更改它。
在不使类Employee不可变的情况下,这是可能的。
我希望班上的员工能够独立存在,所以不想将其建筑私有化 不必公开不可变类的Employee成员。您可以引入只公开员工相关字段的getter方法
public final class X {
private final Employee emp;
public X (Employee e){
this.emp = e.clone ();
}
public String getEmpName(){
return emp.getName();
}
public int getEmpSalary(){
return emp.getSalary();
}
}
当然,还要做一件事来确保类是真正不可变的。构造函数应该创建传递给它的员工的副本。否则,构造函数的调用方仍将拥有对Employee的引用,并且可以更改该对象。您不必公开不可变类的Employee成员。您可以引入只公开员工相关字段的getter方法
public final class X {
private final Employee emp;
public X (Employee e){
this.emp = e.clone ();
}
public String getEmpName(){
return emp.getName();
}
public int getEmpSalary(){
return emp.getSalary();
}
}
当然,还要做一件事来确保类是真正不可变的。构造函数应该创建传递给它的员工的副本。否则,构造函数的调用方仍将有对Employee的引用,并且可以更改该对象。您可以向Employee添加一个副本构造函数,并在其实例传入或传出不可变类时使用它
public final class X {
private final Employee emp;
public X (Employee e){
this.emp = new Employee(e);
}
public Employee getEmp(){
return new Employee(emp);
}
}
话虽如此,您仍然应该认真地重新评估是否最好也使Employee不可变,因为所有这些复制可能会有相当大的开销。您可以向Employee添加一个复制构造函数,并在Employee的实例传入或传出不可变类时使用它
public final class X {
private final Employee emp;
public X (Employee e){
this.emp = new Employee(e);
}
public Employee getEmp(){
return new Employee(emp);
}
}
话虽如此,您仍然应该认真地重新评估是否最好也使员工不可变,因为所有这些复制可能会有相当大的开销。其他人理论上仍然可以更改通过构造函数提交的实例,因此这不是100%安全的解决方案Hey Eran,现在一切都有意义了。谢谢你的信息。因此,如果我不返回带有emp对象的用户,他将无法进行任何修改。其他人理论上仍然可以更改通过构造函数提交的实例,因此这不是100%安全的解决方案。嘿,Eran,现在一切都有意义了。谢谢你的信息。因此,如果我不返回带有emp对象的用户,他将无法进行任何修改。也感谢您提供此选项。我只是对这个设计很好奇。如果我需要实现它,我会记住你说过的话。同样感谢你的选择。我只是对这个设计很好奇。如果我需要实施它,我会记住你说过的话。