Clone Uses Constructor Instead of super.clone()
ID |
java.clone_no_constructor_call |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
CWE:580, clone, reliability |
Rationale
The Cloneable contract requires that cloned objects be obtained by calling super.clone(), which ultimately invokes Object.clone() to produce a field-by-field copy. Using a constructor instead breaks the chain: if a subclass also overrides clone() and calls super.clone(), it will get an instance of the wrong class. The constructor-based approach also silently drops any fields inherited from superclasses.
// Bad -- breaks the clone chain
@Override
public Object clone() {
MyClass copy = new MyClass(); // wrong!
copy.value = this.value;
return copy;
}
Remediation
Use super.clone() and cast the result. Perform deep-copy work for mutable fields after the super call.
// Good -- chains through super.clone
@Override
public Object clone() throws CloneNotSupportedException {
MyClass copy = (MyClass) super.clone();
copy.mutableField = new ArrayList<>(this.mutableField);
return copy;
}