>
>
>
V6052. Calling an overridden method in …


V6052. Calling an overridden method in parent-class constructor may lead to use of uninitialized data.

Выявлен случай использования метода в родительском конструкторе, который в свою очередь переопределяется в дочернем классе. Такое использование может привести к тому, что переопределенный метод будут использовать неинициализированные поля класса.

В JLS [12.5] описан порядок инициализации нового класса, и если пренебречь им, то может наблюдаться такое поведение.

Рассмотрим пример, который приведет к такому случаю:

public class Parent {
  private String parentStr = "Black";

  public Parent () {
    printInfo();
  }

  public void printInfo () {
    System.out.println("Parent::printInfo");
    System.out.println("parentStr: " + parentStr);
    System.out.println("-----------------");
  }
  ....
}

public class Child extends Parent {
  private int childInt;
  private String childStr;

  public Child() {
    super();
    this.childInt = 25;
    this.childStr = "White";
  }

  public void printInfo () {
    super.printInfo();
    System.out.println("Child::printInfo");
    System.out.println("childInt: "+childInt+";childStr: "+childStr);
    System.out.println("-----------------");
  }
  ....
}

Если выполнить следующую строку кода:

Child obj = new Child();

то на экран будет выведен такой текст:

Parent::printInfo
parentStr: Black
-----------------
Child::printInfo
childInt: 0 ; childStr: null
-----------------

По распечатанному фрагменту видно, что был вызван переопределенный метод 'printInfo' из родительского конструктора класса 'Parent', когда дочерний класс 'Child' не был полностью проинициализирован. Отсюда и получается, что поля 'childInt' и 'childStr' распечатаны со значениями по умолчанию, а не с теми, что мы задали.

Вывод: никогда не используйте методы в конструкторе, которые могут быть в дальнейшем переопределены в дочерних классах. Если же в конструкторе используется метод класса, то он должен быть либо final, либо private.

Данная диагностика классифицируется как:

  • CERT-MET05-J