Выявлен случай использования метода в родительском конструкторе, который, в свою очередь, переопределяется в дочернем классе. Такое использование может привести к тому, что переопределенный метод будут использовать неинициализированные поля класса.
В 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.
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V6052. |