I have a class ContainedObject
which instances are supposed to be contained in an ArrayList
.
public class ContainedObject {
private ContainerArrayList<ContainedObject> containningArrayList;
public ContainerArrayList<ContainedObject> getContainningArrayList() {
return containningArrayList;
}
public void setContainningArrayList(ContainerArrayList<ContainedObject> list) {
containningArrayList = list;
}
}
Now, I want to extend ArrayList
in such a way that getContainningArrayList()
of it's contained objects will reflect their "container". For example, I override add()
this way:
public class ContainerArrayList<ContainedObject> extends ArrayList<ContainedObject> {
@Override
public boolean add(ContainedObject e) {
e.setContainningArrayList(this);
return super.add(e);
}
}
So far so good. The thing is, I want to be able to also call ContainerArrayList
copy constructor and clone
methods, etc, and maintain the same containment reflection. So my question is - should I re implement each of these methods, or do they in some way call each other (i.e. ArrayList(ArrayList)
uses add
to construct the new arraylist).
Any leads?
If you want the described behavior you have to override clone method or create a custom constructor (or both) taking Collection as an argument. Using the default methods would make your custom objects point to old containningArrayList.
You can see how things work in ArrayList source code:
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
//Arrays.copyOf returns a copy of the original array, truncated or padded with nulls to obtain the specified length
Also consider turning ContainedObject to interface.