克隆Java中的不可变对象

时间:2013-03-27 22:16:51

标签: java clone immutability

我有一个权重为int的不可变对象,在我的代码中,我需要更新权重,inroder要做到这一点,我需要制作该对象的副本并使用更新的值设置权重。但是对象没有clone()覆盖,我不知道哪种方式更好,clone()或实现Cloneable接口?

这是我的班级:

public class WeightedEdge implements Edge {

    private final WeightedEdgeComparator _weightedEdgeComparator;

    private final Vertex _target;

    private final int _weight;

    WeightedEdge(Bundle bundle, Vertex target, int weight) {
        _weightedEdgeComparator = new EdgeComparator(bundle.getDirection());
        _target = target;
        _weight = weight;
    }

    @Override
    public Vertex target() {
        return _target;
    }

    @Override
    public int weight() {
        return _weight;
    }

        @Override
    public int compareTo(WeightedEdge o) {
        return _EdgeComparator.compare(this, o);
    }

    @Override
    public int hashCode() {...}

    @Override
    public boolean equals(Object obj) { ... }

    @Override
    public String toString() { ... }

3 个答案:

答案 0 :(得分:4)

如何使用新值返回一个新对象:

// as mentioned by AndrewBissell, there is no reference to the bundle
// luckily, we only need the direction from the bundle :)
private final int _direction;

WeightedEdge(Bundle bundle, Vertex target, int weight) {
    this(bundle.getDirection(), target, weight);
}

WeightedEdge(int direction, Vertex target, int weight)
{
    _direction = direction;
    _weightedEdgeComparator = new EdgeComparator(_direction);
    _target = target;
    _weight = weight;

}

WeightedEdge updatedObject(int newWeight)
{
    return new WeightedEdge(_direction, _target, newWeight);
}

答案 1 :(得分:0)

不是将Bundle或可能的方向传递给构造函数,而只是为了在构造函数中使用它们来实例化EdgeComparator,而只需使EdgeComparator构造函数参数,并在WeightedEdge上的字段中存储对它的克隆实例的引用:

WeightedEdge(EdgeComparator comparator, Vertex target, int weight) {
    _weightedEdgeComparator = comparator.clone();
    _target = target;
    _weight = weight;
}

然后你可以WeightedEdge实现Cloneable,并且在构造克隆时你将能够提供所有必要的参数。这也允许您将有关EdgeComparator实施的决定与WeightedEdge实施分开,这是良好的OO实践。

此外,您需要确保Vertex的所有实例都是不可变的,或者可以通过将可变target传递给它来构造此类的可变实例。或者,您也可以在构造函数中克隆target

如果EdgeComparator不可克隆,则除了提供接受并存储对方向的引用的构造函数之外别无选择,如Binyamin Sharet的答案所示。

答案 2 :(得分:0)

您可以使用其他构造函数克隆您的对象,并仅更新权重部分。

WeightedEdge(WeightedEdge wEdge, int weight) {
     //copy all fields of wEdge into THIS object, except weight.  
     //use int weight parameter to set the new weight
}

HTH