Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#FFcccc
class CloneExample implements Cloneable {
  HttpCookie[] cookies;

  CloneExample(HttpCookie[] c) {
    cookies = c;
  }

  public Object clone() throws CloneNotSupportedException {
    final CloneExample clone = (CloneExample) super.clone();
    clone.doSomething(); // Invokes overridable method
    clone.cookies = clone.deepCopy();
    return clone;
  }

  void doSomething() { // Overridable
    for (int i = 0; i < cookies.length; i++) {
      cookies[i].setValue("" + i);
    }
  }

  HttpCookie[] deepCopy() {
    if (cookies == null) {
      throw new NullPointerException();
    }

    // deep copy
    HttpCookie[] cookiesCopy = new HttpCookie[cookies.length];

    for (int i = 0; i < cookies.length; i++) {
      // Manually create a copy of each element in array
      cookiesCopy[i] = (HttpCookie) cookies[i].clone();
    }
    return cookiesCopy;
  }
}

class Sub extends CloneExample {
  Sub(HttpCookie[] c) {
    super(c);
  }

  public Object clone() throws CloneNotSupportedException {
    final Sub clone = (Sub) super.clone();
    clone.doSomething();
    return clone;
  }

  void doSomething() { // Erroneously executed
    for (int i = 0;i < cookies.length; i++) {
      cookies[i].setDomain(i + ".foo.com");
    }
  }

  public static void main(String[] args)
      throws CloneNotSupportedException {
    HttpCookie[] hc = new HttpCookie[20];
    for (int i = 0 ; i < hc.length; i++){
      hc[i] = new HttpCookie("cookie" + i,"" + i);
    }
    CloneExample bc = new Sub(hc);
    bc.clone();
  }
}

If When an overridable method is invoked on a shallow copy of the object, the original object is also modified.

...

Alternative solutions that prevent invocation of overloaded overridden methods include declaring these methods private or final or, declaring the class final, or eliminating the method calls by congregating the codecontaining these methods final.

Risk Assessment

Calling overridable methods on the clone under construction can expose class internals to malicious code or violate class invariants by exposing the clone to trusted code in a partially initialized state, affording the opportunity to corrupt the state of the clone, the object being cloned, or both.

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d48c2909a9a73ef7-3ce58087-420e4c9e-a3639402-fec6e7cd3639c64b02ece125"><ac:plain-text-body><![CDATA[

[[Bloch 2008

AA. Bibliography#Bloch 08]]

Item 11. Override clone judiciously

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8f5b116a3b7453fe-674d8d98-477644ad-a9fa9a06-2d6860d69708f2ee314fefb3"><ac:plain-text-body><![CDATA[

[[Gong 2003

AA. Bibliography#Gong 03]]

 

]]></ac:plain-text-body></ac:structured-macro>

...