【发布时间】:2017-08-11 09:41:26
【问题描述】:
让我们考虑不可变对象File,它封装了指向磁盘上文件的fileName。该对象具有rename 方法,显然是为磁盘上的文件分配新名称。
public final class File {
private final String fileName;
public File(String fileName fileName) {
this.fileName = fileName;
}
public File rename(String newName) {
// Rename the actual file on the disk (code is omitted)
// and that is the side effect!
return new File(newName);
}
}
所以问题是:
- 如何处理不可变对象的副作用?我们的
File对象一旦创建就应该始终以相同的封装状态工作。并返回具有修改状态的新对象。这在java.lang.String类中完美完成。但是旧对象(仍然指向错误fileName)并不好。我们无法使用它,因为状态已损坏。 - 这是否意味着对象不是真正不可变的?如果我们只想使用具有一致状态的真正不可变对象怎么办?我们不应该重命名磁盘上的文件吗?但是当我们真正需要重命名文件时如何完成工作呢?
假设File 只是一个例子。
【问题讨论】:
-
由于不能销毁对象,所以只需要等到旧对象符合被GarbageCollected的条件即可
-
为什么您认为旧文件名是“错误”?它与重命名之前一样有效。只是它指向的文件(文件系统中的一个对象)不存在......
-
@UsagiMiyamoto 因为我不能重用那个特定的对象。它是具有副作用的修改状态。更糟糕的是:旧的
File的所有属性都保持不变,因为对象是不可变的。所以整个对象都坏了。但我明白你的意思。从技术上讲 - 是的。对象仍然是可管理的,但没有用。它仍然与创建时不同。那么它真的是不可变的吗? -
当然可以重复使用。
File代表文件名称,而不是文件,而且文件名不必存在。 -
对。但那是不可能的。鉴于场景和要求,您不能使这些对象 100% 不可变。您仍然可以努力使状态尽可能不可变,但仅此而已。
标签: java oop immutability