1

次のようなコードがあります。

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

そして term.add(anotherTerm)、anotherTerm が... 別の Term オブジェクトのようなことをするたびに、anotherTerm は、term に挿入したものと同じものを参照しているように見えるので、anotherTerm を変更しようとするたびに term.get( 2) (たとえば) get も変更されます。

どうすればこれを防ぐことができますか?

コードが要求されたので:

//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);

anotherTerm 用語を作成するコード:

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

insert メソッドを呼び出す新しいコード:

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

clone() has protected access in java.lang.Object残念ながら、実行した後でも、これはまだ機能しませんpublic class Term implements Cloneable{

4

5 に答える 5

4

解決策は簡単ですTerm。不変にすることです。

有効な Java 2nd Edition、項目 15: 可変性を最小限に抑える:

  • 不変オブジェクトは単純です。
  • 不変オブジェクトは自由に共有できます。
  • 不変オブジェクトは、他のオブジェクトの優れた構成要素になります。
  • クラスを可変にする非常に正当な理由がない限り、クラスは不変であるべきです。
  • クラスを不変にできない場合は、その可変性を可能な限り制限します。
    • finalやむを得ない理由がない限り、すべてのフィールドを作成します。final

シンプルで小さいものは、Term実際には不変にする必要があります。全体的にはるかに優れたデザインであり、質問で尋ねていたようなことを心配する必要はありません.

こちらもご覧ください


このアドバイスは、他の回答が使用を示唆しているため、さらに説得力がありますclone()

有効な Java 2nd Edition、項目 11:clone慎重にオーバーライドする

多くの欠点があるため、一部のエキスパート プログラマーは、cloneメソッドをオーバーライドせず、おそらく配列をコピーする場合を除き、メソッドを呼び出さないことを選択するだけです。

著者 Josh Bloch へのインタビューから:

私の本でクローンに関する項目を読んだことがあるなら、特に行間を読んだなら、私cloneが深く壊れていると思うことがわかるでしょう。

しないでくださいTerm implements Cloneable。代わりに不変にします。

こちらもご覧ください

于 2010-05-06T07:09:11.160 に答える
2

OK、質問と動作をよりよく理解したので、私の古い答えをこれに置き換えます。

必要に応じてこれを行うことができます:

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

次に、次のような新しい Term コンストラクターを作成します。

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

それはうまくいくはずです。

于 2010-05-06T07:07:28.993 に答える
2

編集:わかりました、あなたが今何をしているのか分かります。このクラスがある場合:

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)と同じオブジェクトです。「term」と「poly.get(0)」はどちらも同じオブジェクトへの参照です。一方を変更すると、もう一方も変更されます。

于 2010-05-06T07:15:15.623 に答える
1

質問はそれほど明確ではありませんが、オブジェクトを追加するときに、anotherTerm.clone()を追加してみてください

于 2010-05-06T07:01:02.017 に答える
1

Object同じものを参照しているだけで、新しい s をインスタンス化していないようです。Termを使用するTerm term = new Term();か、クローンを作成することによって、新しい をインスタンス化する必要がありますterm.clone()

EDIT を複製できるようにするには、 CloneableインターフェイスTermを実装する必要があります。つまり、 a の新しいコピーをどのように定義するかは、ユーザーの責任です。Term

メソッドを呼び出すコードを見ないとわかりませんinsertが、それが問題のようです。

于 2010-05-06T07:02:33.183 に答える