Fork me on GitHub

Clone Implementation

The Clone Implementation ruleset contains a collection of rules that find questionable usages of the clone() method.

ProperCloneImplementation

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
    }
}

     

CloneThrowsCloneNotSupportedException

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;
     }
 }
    
         

CloneMethodMustImplementCloneable

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;
 }
}