在对象构造期间调用的 PMD 可重写方法



>我有以下结构

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

你能建议如何解决这个错误吗?

PMD规则说:

在构造期间调用可重写的方法会带来在未完全构造的对象上调用方法的风险,并且可能难以调试。它可能使子类无法构造其超类,或者被迫在自身内完全复制构造过程,从而失去调用super()的能力。如果默认构造函数包含对可重写方法的调用,则子类可能完全不可实例化。请注意,这包括整个控制流图的方法调用 - 即,如果构造函数Foo()调用私有方法bar()调用公共方法buz(),则表示存在问题。

例:

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

溶液

删除对构造函数中可重写方法的任何调用,或向该方法添加 final 修饰符。

也许你可以遵循Java的命名约定,并使Childfinal

public final class Child extends Parent {

很可能有两种方法可以解决此问题。

  1. 您确实可以将构造函数中调用的方法作为final,但它的缺点是子类无法覆盖最终方法。
  2. 若要创建构造函数和可重写方法中使用的私有方法,请参阅下面的代码段。
<小时 />
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
  }
  
}

最新更新