Finalizer Rules

These rules deal with different problems that can occur with finalizers.

EmptyFinalizer

Since: PMD1.5

If the finalize() method is empty, then it does not need to exist.


//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
  /Block[count(*)=0]

                
Example(s):

public class Foo {
   protected void finalize() {}
}

       

FinalizeOnlyCallsSuperFinalize

Since: PMD1.5

If the finalize() is implemented, it should do something besides just calling super.finalize().


//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
   /Block[count(BlockStatement)=1]
     /BlockStatement[
       Statement/StatementExpression/PrimaryExpression
      /PrimaryPrefix[@Image="finalize"]
      ]

                
Example(s):
           
public class Foo {
   protected void finalize() {
     super.finalize();
   }
}
           
       

FinalizeOverloaded

Since: PMD1.5

Methods named finalize() should not have parameters. It is confusing and probably a bug to overload finalize(). It will not be called by the VM.


//MethodDeclaration
 /MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]

            
Example(s):

public class Foo {
   // this is confusing and probably a bug
   protected void finalize(int a) {
   }
}

   

FinalizeDoesNotCallSuperFinalize

Since: PMD1.5

If the finalize() is implemented, its last action should be to call super.finalize.



//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
   /Block
      /BlockStatement[last()]
      [not(Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image='finalize'])]
      [not(Statement/TryStatement/FinallyStatement
       /Block/BlockStatement/Statement/StatementExpression
        /PrimaryExpression/PrimaryPrefix[@Image='finalize'])]

                
Example(s):

public class Foo {
   protected void finalize() {
       something();
       // neglected to call super.finalize()
   }
}

       

FinalizeShouldBeProtected

Since: PMD1.1

If you override finalize(), make it protected. If you make it public, other classes may call it.

                    
//MethodDeclaration[@Protected="false"]
  /MethodDeclarator[@Image="finalize"]
  [not(FormalParameters/*)]
                    
                
Example(s):
  
public class Foo {
 public void finalize() {
  // do something
 }
}
  
      

AvoidCallingFinalize

Since: PMD3.0

Object.finalize() is called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

This rule is defined by the following Java class:net.sourceforge.pmd.lang.java.rule.finalizers.AvoidCallingFinalizeRule

Example(s):

public class Foo {
 void foo() {
  Bar b = new Bar();
  b.finalize();
 }
}