Project

General

Profile

Why clone() children in addChildren()?

Gabriel Rossetti
Added over 4 years ago

Hi,

I was making an Element and while debugging I noticed something, addChild() does as it says, it adds the given child element to the children structure, as expected. addChildren() however does not do that, it adds a clone (which is wy my code breaks), why does it do that? Why not add the children without cloning them? For now I will change my code to work around this but it will be slower. My use-case is I add children but later on I modify them, I exprected this to be reflected in the Element but it was not.

        /**
     * Method description
     *
     * @param child
     */
    public void addChild(XMLNodeIfc child) {
        if (child == null) {
            throw new NullPointerException("Element child can not be null.");
        }
        if (children == null) {
            children = new LinkedList<XMLNodeIfc>();
        }    // end of if (children == null)
        synchronized (children) {
            children.add(child);

            // Collections.sort(children);
        }
    }

    /**
     * Method description
     *
     * @param children
     */
    public void addChildren(List<Element> children) {
        if (children == null) {
            return;
        }    // end of if (children == null)
        if (this.children == null) {
            this.children = new LinkedList<XMLNodeIfc>();
        }    // end of if (children == null)
        synchronized (this.children) {
            for (XMLNodeIfc child : children) {
                this.children.add(child.clone());           <-- why clone?
            }    // end of for (Element child: children)

            // this.children.addAll(children);
            // Collections.sort(children);
        }
    }

Replies (1)

Avatar?id=6023&size=32x32

Added by Artur Hefczyc TigaseTeam over 4 years ago

why does it do that? My use-case is I add children but later on I modify them,

This is the exact reason why cloning is used. To avoid accidental changes in the Element by making changes in another Element which shares the same children. Elements (Packets) in Tigase should be considered, more or less, as immutable objects. This immutability is not enforced, it is more a convention because in certain use-cases we can have special optimizations that require Packet modifications but this has to be done very carefully.

If you really want to avoid cloning, you have to use addChild(...) instead of addChildren(...).

    (1-1/1)