Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不变类_Java_String_Immutability - Fatal编程技术网

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测试的旧代码中尤其令人恼火。。。