我知道如何创建immutable class
。我创建了以下内容。
public class Employee {
private final int id;
private final String name;
private final int salary;
public Employee(int id, String name, int salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getSalary() {
return salary;
}
}
很少有文章也暗示,您将自己的课程声明为final
,即使是有效的JAVA 一书也说“将您的方法标记为最终,以便不会覆盖”< / strong>。但是,当字段被声明为final
以及setter
时,我无法理解为什么我需要在课程或private
方法上使用final
?
或者文章和EFFECTIVE JAVA提出了另一种方法!!!
答案 0 :(得分:2)
制作课程immutable
并将课程声明为final
具有不同的含义。如果您创建类final
,则意味着您无法覆盖方法中的任何功能(方法),这与immutablity
不同。
即使您将field
作为最终版本,我仍然可以extend
class
,并覆盖其他方法,例如在您返回的方法getName
中{{1}我可以覆盖该方法,我可以使employee name
返回method
。
查看示例:
employee name + employee id
来自Java Doc Strategy for Defining Immutable Objects
public class SubEmployee extends Employee{
public String getName(){
return "Darth Vader";
}
}
答案 1 :(得分:2)
正如其他人所解释的那样,它可以防止子类改变父类的行为。引用 Effectice Java
确保无法扩展课程。这可以防止粗心或 恶意子类破坏了不可变的行为 通过表现就好像对象的状态已经改变一样。预防 子类化通常是通过使类最终完成而完成的 我们将在稍后讨论一种替代方案。
以下是一个例子:
public class Manager extends Employee {
public Manager(int id, String name, int salary) {
super(id, name, salary);
}
@Override
public String getName() {
return "doppelganger";
}
public static void main(String[] args) {
Employee e = new Manager(0, "Eric", 100); //e should be immutable right!
System.out.println(e.getName()); // prints "doppelganger", I thought employee was immuatble!?
}
}
答案 2 :(得分:1)
如果你没有让Employee类或者最后的所有方法结束,我可以编写一个可变的MyEmployee类。然后我可以将它传递给任何需要Employee的方法。如果您的代码依赖于Employee是不可变的这一事实,那么当ID发生变化时会非常惊讶,因为它是一个MyEmployee,而不仅仅是一个Employee。
public class MyEmployee extends Employee {
private final int id;
public MyEmployee(int id, String name, int salary) {
super(id, name, salary);
this.id = id;
}
public int getId() {
return this.id;
}
public void setId(final int id) {
this.id = id;
}
答案 3 :(得分:0)
首先,您需要了解最终访问和私人访问之间的区别。当您将方法声明为Private时,并不意味着您无法覆盖它。类上的Final关键字使得类不可访问,并且on方法使非覆盖和on变量为常量。最好在setter上使用Final Keyword,以避免使用它的任何其他类的无意更改。