java - 我怎样才能使这个对象可变

标签 java immutability mutable

我有这个简单的不可变对象(immutable对象):

public class Alt {
public LinkedList<Integer> list = new LinkedList<Integer>();

public void refresh() {
    Random rand = new Random();

    list.clear();

    for (int i = 0; i < 50; i++) {
        list.add(rand.nextInt(32));
    }
}

public void compare(Alt alt) {
    for (int i = 0; i < list.size(); i++) {
        System.out.println(alt.list.get(i) + " " + list.get(i));
      }
   }
}

但是这个类是一个不可变的对象,例如当我运行时:

Alt a = new Alt();
a.refresh();
Alt b = a;
b.refresh();

a.compare(b);

返回的值是相同的,对象 b 就像对象 a 的快捷方式一样,或多或少是重复的。有没有办法让 b 分开?或者我这样做的方式完全错误。

最佳答案

你的术语是错误的。这不是一个不可变的对象。 refresh() 方法修改对象。下面的代码将输出两行不同的内容:

Alt a = new Alt();
a.refresh();
System.out.println(a.list);
a.refresh();
System.out.println(a.list);

此外,由于字段 list 从类外部可见,因此可以直接修改它:

Alt a = new Alt();
a.refresh();
System.out.println(a.list);
a.list.set(10, 42);
System.out.println(a.list);

您观察到的行为是由于 a = b 没有创建该对象的新副本所致。它仅使引用 b 指向与引用a 相同的对象。由于只有一个对象,a.compare(b) 将打印相同的数字两次。

要复制该对象,您必须自己对其进行编程。在 Java 中,这通常由所谓的复制构造函数完成:

public Alt(Alt original) {
    list = new LinkedList<>(original.list);
}

(请注意复制构造函数如何调用 LinkedList 的复制构造函数,这会生成列表的副本。)

现在你可以写:

b = new Alt(a);

然后b将是对恰好包含相同数据的新对象的引用。

关于java - 我怎样才能使这个对象可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45810874/

相关文章:

java - 动态添加时单选按钮文本颜色问题

java - <html> 和 <html :html> element in JSP? 之间有什么区别

java - 不可变是什么意思?

java - 如何创建由 Map 支持的可变列表

scala - 没有 Scala 可变列表

java - 无法将 java spring boot 中的文件上传到 tomcat 托管服务器,始终显示对 fedora 中给定文件上传路径的访问权限

java - 简单的代码无法输出所有所需的结果

java - 享元模式对象是不可变的?

java - 可变类作为不可变类的子类

python - 我如何证明该函数在 Python 中是可变的?