Question

I have code that looks like this:

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

and it seems that whenever I do something like term.add(anotherTerm), with anotherTerm being... another Term object, it seems anotherTerm is referencing the same thing as what I've just inserted into term so that whenever I try to change anotherTerm, term.get(2) (let's say) get's changed too.

How can I prevent this from happening?

Since code was requested:

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

Code calling the insert method:

poly.insert(anotherTerm);

Code creating the anotherTerm Term:

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

New code calling the insert method:

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

Which unfortunately still doesn't work due to clone() has protected access in java.lang.Object, even after doing public class Term implements Cloneable{

Was it helpful?

Solution

OK, replacing my old answer with this, now that I understand the question and behavior better.

You can do this if you like:

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

and then create a new Term constructor like this:

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

That should work.

OTHER TIPS

The solution is simple: make Term immutable.

Effective Java 2nd Edition, Item 15: Minimize mutability:

  • Immutable objects are simple.
  • Immutable objects can be shared freely.
  • Immutable objects make great building blocks for other objects.
  • Classes should be immutable unless there's a very good reason to make them mutable.
  • If a class cannot be made immutable, limit its mutability as much as possible.
    • Make every field final unless there is a compelling reason to make it non-final

Something as simple and small as Term really should be made immutable. It's a much better overall design, and you wouldn't have to worry about things like you were asking in your question.

See also


This advice becomes even more compelling since the other answers are suggesting that you use clone().

Effective Java 2nd Edition, Item 11: Override clone judiciously

Because of the many shortcomings, some expert programmers simply choose to never override the clone method and never invoke it except, perhaps, to copy arrays.

From an interview with author Josh Bloch:

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken.

DO NOT make Term implements Cloneable. Make it immutable instead.

See also

EDIT: Ok, I think I see what it is you're doing now. If you have this class:

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

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

And then you do this:

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

...then the object term is the same object as poly.get(0). "term" and "poly.get(0)" are both references to the same object - changing one will change the other.

Question is no so clear, but i just try , when you are adding the objects , add anotherTerm.clone()

It sounds like you are not instantiating new Objects, just referencing the same one. You should instantiate a new Term, either with Term term = new Term(); or by cloning term.clone().

EDIT to be able to be cloned, Term need to implement the Cloneable interface. That means that you are responsible for how the new copy of a Term should be defined.

Hard to tell without seeing the code that calls the insert method, but sounds like that is the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top