0

我有以下课程:

Emp.java

final public class Emp {

    private Integer id;
    private String name;
    private Department department;

    public Emp(Integer id, String name, Department department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    public Department getDepartment() {
        return department;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

部门.java

public class Department {

    private Integer id;
    private String name;

    public Department(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setId(Integer id) {
        this.id = id;
    }

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

EmployeeTest.java

public class EmployeeTest {

    public static void main(String args[]) {
        Department dept1 = new Department(1, "dept1");
        Emp emp = new Emp(1, "emp1", dept1);
        emp.getDepartment().setName("dept2");
        System.out.println("emp = "+emp);

    }
}

这里Emp类不是纯粹的不可变类,因为我能够以某种方式更改Department的值(如示例所示)。

使Emp类成为纯 Immutable 类的最佳更改是什么?

4

5 回答 5

3

在非原始字段的 吸气剂中,使用此结构

public class Line {

   private final Point start;
   private final Point end;

   public Line(final Point start, final Point end) {
       this.start = new Point(start);
       this.end = new Point(end);
   }

   public Point getStart() {
       return new Point(start);
   }

   public Point getEnd() {
       return new Point(end);
   }
}  

因此,只需创建与先前相同的部门的新实例

PS在我的示例中,您可以看到纯不可变类
编辑:
您也可以添加到部门类复制构造器

public Department(final Department dep)  
{ ... } 

和雇主

getDepartment()  
{  
   return new Department(department);  
}
于 2012-08-20T09:15:38.950 回答
1

如果您不喜欢删除 setter 并在构造函数中进行初始化,您可以考虑Emp在 getter 中返回不可变(从类的角度来看)对象,这将是 Web 对象的副本(请参阅https://stackoverflow.xml )。 com/a/128712/1579085)。

final public class Emp {

    private Integer id;
    private String name;
    private Department department;

    public Emp(Integer id, String name, Department department) {
        this.id = id;
        this.name = name;
        this.department = (Department) department.clone();
    }

    public Department getDepartment() {
        return (Department) department.clone();
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

并实现方法clone()Department将实现接口Cloneable)当然。

如果您需要能够修改Department,这种方法是合适的,但Emp类的对象应该不受那些外部修改的影响。

于 2012-08-20T09:31:45.353 回答
1

请参阅有效的 Java:

第 15 项:最小化可变性——要遵循的 5 条规则。

  1. 不要提供任何修改对象状态的方法
  2. 确保类不能扩展
  3. 使所有字段最终
  4. 将所有字段设为私有
  5. 确保对任何可变组件的独占访问权
于 2012-08-20T09:33:41.597 回答
0

制作所有属性final,并删除所有设置器

于 2012-08-20T09:08:26.730 回答
0

在 Department 中实现clone()并让EmpgetDepartment()中返回一个部门的克隆。

如果在构造后对用于构造 Emp 的 Department 的引用可用,则 Emp 的构造函数应该克隆给定的 Department。

于 2012-08-20T09:09:52.023 回答