Number 子类的防御性拷贝

7
请看以下示例:
public final class ImmutableWrapper<T extends Number> {

    private final T value;

    public ImmutableWrapper(T value) {
        // a subclass of Number may be mutable
        // so, how to defensively copying the value?
        this.value = value;
    }

    public T getValue() {
        // the same here: how to return a copy?
        return value;
    }
}

为了使这个类不可变,我必须在构造函数中防御性地拷贝任何可变参数,并在公共方法返回的内部可变对象上创建副本。
这可行吗?如果不行,是否有任何解决方法?

你为什么想这样做呢?在javadoc中声明,如果数字在多线程环境下发生变异,则类的行为是未定义的,这不是更简单吗? - assylias
1
@assylias 例如,我在Guava的Range中看到了有关在javadoc中将可变对象传递给构造函数的警告。不管怎样,这是我的最后选择。 - Paolo Fulgoni
除非你担心恶意代码会破坏你的代码,否则这是一个完全合理的选择。 - assylias
2个回答

3

所有的Number类型都是Serializable的,因此您可以通过进行序列化/反序列化来创建副本。

也许您可以使用apache commons-lang的SerializationUtils.clone(Serializable)函数。

public final class ImmutableWrapper<T extends Number> {

    private final T value;

    public ImmutableWrapper(T value) {
        // a subclass of Number may be mutable
        // so, how to defensively copying the value?
        this.value = SerializationUtils.clone(value);
    }

    public T getValue() {
        // the same here: how to return a copy?
        return  SerializationUtils.clone(value);
    }
}

如果你想自己实现它,请看一下:


0
你需要克隆对象。所以你的代码应该像这样:
public final class ImmutableWrapper<T extends Number> {
    private final T value;

    public ImmutableWrapper(T value) {
        this.value = value.clone();
    }

    public T getValue() {
        return value.clone();
    }
}

数字也没有实现Cloneable。 - assylias
刚刚将这段代码粘贴到 Eclipse 中。编译器对 value.clone() 不满意,因为在 Object 上不可见 clone() 方法。 - Harald
@Paolo,请参考Rene Links上面的答案。他是正确的,克隆方法是受保护的。 - mikea
@mikea,我理解了关于克隆方法的问题。我只是想知道是否使用cloning库(它不依赖于Java的Clonable接口,而是利用反射来复制对象)可能是另一个不错的选择。 - Paolo Fulgoni
@Paulo 这是一个可能的选项,但可能不如 SerializationUtils 高效。反射是一个臭名昭著的 CPU 占用工具。 - mikea
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接