The Clone Implementation ruleset contains a collection of rules that find questionable usages of the clone() method.
Since: PMD 1.4
Priority: 2
Object clone() should be implemented with super.clone().
//MethodDeclarator [@Image = 'clone'] [count(FormalParameters/*) = 0] [count(../Block//*[ (self::AllocationExpression) and (./ClassOrInterfaceType/@Image = ancestor:: ClassOrInterfaceDeclaration[1]/@Image) ])> 0 ]
Example(s):
class Foo{ public Object clone(){ return new Foo(); // This is bad } }
Since: PMD 1.9
Priority: 3
The method clone() should throw a CloneNotSupportedException.
//MethodDeclaration [ MethodDeclarator/@Image = 'clone' and count(MethodDeclarator/FormalParameters/*) = 0 and count(NameList/Name[contains (@Image,'CloneNotSupportedException')]) = 0 ] [ ../../../../ClassOrInterfaceDeclaration[@Final = 'false'] ]
Example(s):
public class MyClass implements Cloneable{ public Object clone() { // will cause an error MyClass clone = (MyClass)super.clone(); return clone; } }
Since: PMD 1.9
Priority: 3
The method clone() should only be implemented if the class implements the Cloneable interface with the exception of a final method that only throws CloneNotSupportedException.
//ClassOrInterfaceDeclaration [not(./ImplementsList/ClassOrInterfaceType [@Image='Cloneable'])] /ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration [MethodDeclaration [MethodDeclarator[@Image = 'clone' and count(FormalParameters/*) = 0]] [not((../MethodDeclaration[@Final = 'true'] or ancestor::ClassOrInterfaceDeclaration[1][@Final = 'true']) and Block[count(BlockStatement)=1] /BlockStatement/Statement/ThrowStatement/Expression /PrimaryExpression/PrimaryPrefix/AllocationExpression /ClassOrInterfaceType[@Image = 'CloneNotSupportedException'])]]
Example(s):
public class MyClass { public Object clone() throws CloneNotSupportedException { return foo; } }