java - 不可变类型需要复制构造函数吗?

标签 java immutability

假设我有一个不可变的 DecimalNumber 类:

public final class DecimalNumber {

    public final String str;

    public DecimalNumber(String str) { this.str = str; }
    public DecimalNumber(DecimalNumber copy) { this(copy.str); }

    public boolean isZero() {...}

    public DecimalNumber add(DecimalNumber other) {...}

    ...

}

我决定像这样实现 add:

public DecimalNumber add(DecimalNumber other) {

    if (other.isZero())
        return /* the same object */

    ...

}

我应该返回this(更少的内存使用)还是复制的对象new DecimalNumber(this)

我认为简单地返回 this 应该没问题,但是创建新对象是否有任何好处或原因,或者它是否是首选?

最佳答案

如果一个类是不可变的和最终的,那么你可以返回this

如果它不是最终的,你不能确定 this 实例真的是不可变的。您实际上可能正在处理一个添加了可变状态的子类。

请注意,只有在以下情况下,类才是真正不可变的:

  • 它的所有字段都是最终的,即使是私有(private)字段。 (由于 Java 内存模型允许其他线程查看非最终字段的未完成/默认值,因此仅具有 getter 的非最终字段是不够的。)
  • 它的所有字段本身都是不可变的类,或者对它们的访问受到限制,因此您可以确保它们永远不会被更改。

在您的情况下,满足这两个条件,因为 String 是一个不可变类。如果您知道您的类不存在子类,那么您可以(事实上,恕我直言)返回 this。为确保您的类的子类不存在,您可以将其设置为 final

关于java - 不可变类型需要复制构造函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41692451/

相关文章:

javascript - 如何防御性地防止 Redux 状态的突变?

java - 为什么我会得到 java.lang.IllegalArgumentException : No line matching interface SourceDataLine supporting format MPEG1L3 44100. 0 ....

java - 是否可以通过 WMQTT java 实现提供用于身份验证的用户名/密码?

java - 多主复制

python - Python 中的不变性和线程安全

javascript - Redux:修改Reducers中的状态,可以接受吗?

java - 从文本文件 : not all data stored, 创建嵌套 HashMap 可能会被覆盖

java - 在我通过电子邮件发送给自己后,android 中文件上的 md5 校验和与 md5 不匹配

.net - 在 .NET 中使用 Hashtable 将指针映射到不可变对象(immutable对象)

android - 将不可变位图文件转换为可变位图