Java 不变类
我知道如何创建一个Java 不变类,java,string,immutability,Java,String,Immutability,我知道如何创建一个不可变类。我创建了以下内容 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; thi
不可变类
。我创建了以下内容
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书中也说“将方法标记为final,这样它们就不会被重写”。但我无法理解,当字段被声明为private
和final
时,为什么我需要在类或setter
方法上使用final
或者文章和有效的JAVA推荐了一种替代方法 首先,您需要了解最终访问和私有访问之间的区别。当您将一个方法声明为Private时,并不意味着您不能重写它。类上的Final关键字使类不可访问,方法上的Final关键字使非重写,变量上的Final关键字使其成为常量。最好在setters上使用Final关键字,以避免使用它的任何其他类的无意更改。首先,您需要了解Final和Private访问之间的区别。当您将一个方法声明为Private时,并不意味着您不能重写它。类上的Final关键字使类不可访问,方法上的Final关键字使非重写,变量上的Final关键字使其成为常量。最好在setters上使用Final关键字,以避免使用它的任何其他类的意外更改。使类
不可变,并将类声明为Final
具有不同的含义。如果将类设置为final,则意味着不能重写方法中的任何功能(方法),这与不可变性不同。
即使您将字段
设为最终字段,我仍然可以扩展您的类
,并覆盖其他方法,例如在您的方法getName
中返回员工姓名
,我可以重写该方法,并使方法
返回员工姓名+员工id
参见示例:
public class SubEmployee extends Employee{
public String getName(){
return "Darth Vader";
}
}
来自Java文档
使类不可变
和将类声明为最终
具有不同的含义。如果将类设置为final,则意味着不能重写方法中的任何功能(方法),这与不可变性不同。
即使您将字段
设为最终字段,我仍然可以扩展您的类
,并覆盖其他方法,例如在您的方法getName
中返回员工姓名
,我可以重写该方法,并使方法
返回员工姓名+员工id
参见示例:
public class SubEmployee extends Employee{
public String getName(){
return "Darth Vader";
}
}
来自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!?
}
}
正如其他人所解释的,其目的是防止子类更改父类的行为。引文
确保该类不能扩展。这可以防止粗心或错误
恶意的子类会破坏
通过表现为对象的状态已更改来初始化。阻止
子类化通常通过使类成为最终类来完成,但是
有一个替代方案,我们将在稍后讨论
下面是一个例子:
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!?
}
}
如果不将Employee类设置为final或其上的所有方法设置为final,我可以编写一个可变的MyEmployee类。然后,我可以将其传递到任何需要员工的方法中。如果您的代码依赖于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;
}
如果不将Employee类设置为final或其上的所有方法设置为final,我可以编写一个可变的MyEmployee类。然后,我可以将其传递到任何需要员工的方法中。如果您的代码依赖于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;
}
您能给出一个可以重写私有方法的示例代码吗?私人成员不是继承的,我不认为凌驾于此是可能的。请分享示例代码。不幸的是,声明为final的类有时更难进行单元测试。并不是所有的单元测试框架都能有效地模拟最后一个类,并且覆盖那些干扰测试的方法几乎是不可能的。final在未经junit测试的旧代码中尤其令人恼火……您能给出一个可以重写私有方法的示例代码吗?私人成员不是继承的,我不认为凌驾于此是可能的。请分享示例代码。不幸的是,声明为final的类有时更难进行单元测试。并不是所有的单元测试框架都能有效地模拟最后一个类,并且覆盖那些干扰测试的方法几乎是不可能的。final在未经junit测试的旧代码中尤其令人恼火。。。