0

I am having a list of company objects. I am trying to clone this list with:

public static List<Company> cloneList(List<Company> list) {
    List<Company> clone = new ArrayList<Company>(list.size());
    for(Company item: list) clone.add(item.clone());
    return clone;
}

However my compiler says:

Multiple markers at this line
    - The method add(Company) in the type List<Company> is not applicable for the arguments 
     (Object)

Why is this not possible to make a deep copy with clone()?

user2051347
  • 1,609
  • 4
  • 23
  • 34

4 Answers4

1

The problem is because item.clone() is returning an Object.
You can typecast here. So try changing it to this:

clone.add((Company)item.clone());

Also, override clone in your Company class.
The most simple way of doing it would be this one.

public Object clone(){
   return super.clone();
}

But you may come up with some custom implementation too.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
1

The clone() method is defined on the root class Object (see here). It returns an Object, therefore, if you haven't changed its return type to the concrete class while overriding, you have to cast it to the proper type, e.g. :

clone.add((Company) item.clone());

or define clone() with a covariant return type in your class as:

public class Company implements Cloneable {
   // stuff ...

   public Company clone() throws CloneNotSupportedException { /* do clone */ }
}    

Note that you have to override the clone method as it is defined with visibility protected.

By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method. [source]

Also see this question for other options.

Community
  • 1
  • 1
Pyranja
  • 3,529
  • 22
  • 24
  • Thx for your answer! However my compiler now gives me back: `The method clone() from the type Object is not visible` – user2051347 Feb 07 '14 at 10:17
  • Thx for your answer! What would you put into `/* do clone */`? – user2051347 Feb 07 '14 at 10:24
  • 1
    Code that creates a copy of the object using super.clone and then replaces all references to mutable state, which may not be shared, with a copy of that state. This also applies to state that is transitively reachable. Implementing clone can get complex quickly. I would advise you to not use clone(). Use a copy constructor or copy factory instead. – Pyranja Feb 07 '14 at 10:36
1

You are confusing cloning and genericity.

In your case you simply need to cast your clone as so :

clone.add((Company)item.clone());

Also make sure you deep clone your objects by overrriding the Object#clone method (see Object.clone() :

Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

Laurent B
  • 2,200
  • 19
  • 29
-1

clone() is implemented by Object and returns an Object. Override clone() in your class OR cast your result to Company.

clone.add((Company) item.clone());

gerbenk
  • 21
  • 3