java - 非最终类可以完全不可变吗?

标签 java immutability

没有final修饰符的类可以完全不可变吗?

例如,下面的类是不可变的吗?

class Animal
{
    private String animalName;

    public Animal(String name) {
        animalName = name;
    }

    public String getName() { return animalName; }
}

最佳答案

是的。

该类(如您的问题中所述)是不可变的,因为其内部状态都不会改变。即使您要定义 Animal 类的子类,它也无法更改 animalName;然而,虽然 Animal 类是不可变的,但它的子类可能是也可能不是不可变的(取决于它们的实现)。

这样做的危险在于,如果有人将子类定义为 Animal 类中的内部类(如下所示),那么他们可能会违反您的不变性:

class Animal {
    private String animalName;
    public Animal(String name) {
        animalName = name;
    }
    public getName() { return animalName; }

    public class Eagle extends Animal {
        public Eagle() {
            super("Eagle");
        }
        public void foo() {
            animalName = animalName + "!";
        }
    }
}

因此,只要有可能,最好使用 private 可见性和 final 修饰符。这将防止人们意外地引入违反您打算施加的不变性或封装约束的代码。这样,程序员必须有意识地决定增加可见性或删除 final 关键字,因此他们不会引入任何上述“意外”。

关于java - 非最终类可以完全不可变吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7976589/

相关文章:

java - 使用 java.sql.Connection 在运行时抛出 AbstractMethodError

java - arraylist vs linked list。为什么最后添加时链表变慢?

java - 当泛型类型具有继承结构时,如何在 Mapstruct 中映射集合?

kotlin - 我们可以依靠Gson修改val属性的能力吗?

c# - 如果委托(delegate)是不可变的,为什么我可以做 x += y 这样的事情?

Java - Getter/Setter、行为和接口(interface)

java - Java 变量如何与自身不同?

java - 字符串是不可变的。究竟是什么意思?

f# - 可变值和不可变值重定义有什么区别?

f# - 什么是惯用的 F# 等同于声明一个变量供以后在 C# 中使用