假设我在Java中有一个简单的类来存储时间戳:
public final class Timestamp {
private final long value;
public Timestamp(final long value) {
this.value = value;
}
public long getValue() {
return value;
}
}
那是不可改变的。但是如果不是getValue()
我会编写一个名为getProgress()
的方法呢?
public final class Timestamp {
private final long value;
public Timestamp(final long value) {
this.value = value;
}
public float getProgress() {
return (SomeExternalPlace.getTimestamp() - value) / SomeFloatConstant;
}
}
对象的状态永远不会改变,但getProgress()
的值会随时间发生变化。
后一类被认为是不可变的吗?为什么或为什么不呢?
答案 0 :(得分:1)
它是不可变的,因为一旦创建了value
的实例,其状态(Timestamp
字段)就无法更改。时间戳表示某个时间点,无法更改。
从方法返回的数据不一定必须始终相同。
此外,Timestamp
展示了您对不可变对象所期望的所有属性(例如,线程安全性)。
这是不可变性的另一个“奇怪”的例子:
class LazyList<T>
{
private readonly T _head;
private LazyList<T> _tail;
private readonly Func<LazyList<T>> _tailDelegate;
private bool _created;
public LazyList(T head, Func<LazyList<T>> tailDelegate)
{
_head = head;
_tailDelegate = tailDelegate;
_created = false;
}
public T GetHead()
{
return _head;
}
public LazyList<T> GetTail()
{
if(! _created)
{
_tail = _tailDelegate();
_created = true;
}
return _tail;
}
}
正如您所看到的,_tail
不是真正不可变 - 当实例化LazyList<T>
时它为空,并且仅在客户端调用{{1}时才分配}。但那真的没关系。一旦尾部被创建,它就不会改变;在此之前,尾巴仍然“存在”,它还没有实现。
这实际上是Scala的不可变Stream
的实现方式。