java 在对象构造期间调用PMD Overridable方法

vkc1a9a2  于 2023-04-04  发布在  Java
关注(0)|答案(3)|浏览(150)

我有以下结构

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

你能告诉我怎样解决这个错误吗?

olmpazwi

olmpazwi1#

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修饰符。

yv5phkfx

yv5phkfx2#

也许您可以遵循Java的命名约定,并将Child类设置为final

public final class Child extends Parent {
p3rjfoxz

p3rjfoxz3#

最有可能的两种方法来解决这个问题。
1.你真的可以将在构造函数中调用的方法设置为final,但它的缺点是子类不能覆盖最终的方法。
1.要创建一个在构造函数和可重写方法中使用的私有方法,请参见下面的代码片段。

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

  }
  
}

相关问题