12

I have the following structure

public class parent {
    int value ; 
}

public class child extends parent {
    int childValue;
    public child(){}
    public child (int value){
          this.childValue = value ; // this line cause ConstructorCallsOverridableMethod warning during object construction
    }
}

Could you please advice how to solve this error ?

N00b Pr0grammer
  • 4,503
  • 5
  • 32
  • 46
User
  • 573
  • 3
  • 15
  • 28

3 Answers3

17

The PMD rule says:

Calling overridable methods during construction poses a risk of invoking methods on an incompletely constructed object and can be difficult to debug. It may leave the sub-class unable to construct its superclass or forced to replicate the construction process completely within itself, losing the ability to call super(). If the default constructor contains a call to an overridable method, the subclass may be completely uninstantiable. Note that this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a private method bar() that calls a public method buz(), this denotes a problem.

Example:

public class SeniorClass {
  public SeniorClass(){
      toString(); //may throw NullPointerException if overridden
  }
  public String toString(){
    return "IAmSeniorClass";
  }
}
public class JuniorClass extends SeniorClass {
  private String name;
  public JuniorClass(){
    super(); //Automatic call leads to NullPointerException
    name = "JuniorClass";
  }
  public String toString(){
    return name.toUpperCase();
  }
}

Solution

Delete any call to overridable methods in the constructor or add the final modifier to that methods.

Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
2

Perhaps you could follow follow Java's Naming Conventions and also make the Child class final

public final class Child extends Parent {
Reimeus
  • 158,255
  • 15
  • 216
  • 276
0

There are most likely 2 ways to fix this issue.

  1. Can you indeed make the method that are called in the constructor as final, but it comes with the drawback that subclasses would not be able to override the final method.
  2. To create a private method used in constructor and overridable method, see snippet bellow.

public class Parent {
  
  private int counter;
  public Parent() {
    // setCounter(0); // this line raise the PMD warning
    updateCounter(0);
  }
  private void updateCounter(int counter) {
    this.counter = counter;
  }

  public void setCounter(int counter) {
    updateCounter(counter);
  }

}

public class Child extends Parent {
  
  public void setCounter(int counter) {
    super.setCounter(counter);
    // do other stuff

  }
  
}
Pierrick
  • 600
  • 4
  • 11