我有看起来像这样的代码:

public class Polynomial {
    List<Term> term = new LinkedList<Term>();

似乎每当我做类似的事情 term.add(anotherTerm), ,另一个术语是……另一个术语对象,似乎另一个术语是引用与我刚刚插入的术语相同的东西,以便每当我尝试更改另一个术语时,术语。 。

我如何防止这种情况发生?

由于请求代码:

//since I was lazy and didn't want to go through the extra step of Polynomial.term.add
public void insert(Term inserting) {
    term.add(inserting);
}

调用插入方法的代码:

poly.insert(anotherTerm);

创建另一个术语的代码:

Term anotherTerm = new Term(3, 7.6); //sets coefficient and power to 3 and 7.6

调用插入方法的新代码:

poly.insert((Term)anotherTerm.clone());

不幸的是,由于 clone() has protected access in java.lang.Object, ,即使在做 public class Term implements Cloneable{

有帮助吗?

解决方案

好的,现在我更好地理解问题和行为,以取代我的旧答案。

如果您愿意,可以这样做:

public void insertTerm(Term term) {
    polynomial.insert(new Term(term));
}

然后创建一个这样的新术语构造函数:

public Term(Term term) {
    this.coefficient = term.coefficient;
    this.exponent = term.exponent;
}

那应该起作用。

其他提示

解决方案很简单: Term 不变。

有效的Java第二版,第15项:最小化可变性:

  • 不变的物体很简单。
  • 不变的对象可以自由共享。
  • 不变的物体为其他物体提供了很好的构建块。
  • 除非有充分的理由使其可变,否则课程应该是不变的。
  • 如果不能使某个类不变,请尽可能限制其可突变性。
    • 做每个领域 final 除非有令人信服的理由使其非final

像简单而小的东西 Term 真的应该使不变。这是一个更好的总体设计,您不必担心自己在问题中提出的事情。

也可以看看


由于其他答案建议您使用,因此此建议变得更加引人注目 clone().

有效的Java第二版,项目11:覆盖 clone 明智地

由于存在许多缺点,一些专家程序员只是选择永不覆盖 clone 方法,从不调用它,除了复制阵列外。

从一个 作家乔什·布洛克(Josh Bloch)的访谈:

如果您已经阅读了有关我的书中克隆的物品,尤其是如果您在两行之间阅读,您会知道我认为 clone 被深深打破。

不要 制作 Term implements Cloneable. 。使其不变。

也可以看看

编辑: 好的,我想我知道你现在在做什么。如果您有此类:

public class Polynomial 
{
    List<Term> term = new LinkedList<Term>();

    public void insert(Term inserting) 
    {
       term.add(inserting);
    }
}

然后您这样做:

Polynomal poly = new Polynomal()
Term term = new Term();
poly.insert(term);
term.coefficient = 4;

...然后对象项是 相同 对象为poly.get(0)。 “术语”和“ poly.get(0)”都是对同一对象的引用 - 更改一个会更改另一个对象。

问题不是那么清楚,但是我只是尝试,当您添加对象时,添加enternterm.clone()

听起来您没有实例化新的 ObjectS,只是引用相同的一个。您应该实例化新的 Term, ,要么 Term term = new Term(); 或克隆 term.clone().

编辑要克隆, Term 需要实施 可克隆 界面。这意味着您应对新副本的新副本负责 Term 应定义。

很难看不见呼叫的代码 insert 方法,但听起来像是问题所在。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top