Subclase final con un método sobregrabable de la superclase llamado desde el constructor – Spotbugs
Si una subclase final llama a un método sobreescrito de una superclase desde el constructor, Spotbugs reporta un error (ver nota a continuación para más detalles).
¿Es esto esperado o es un problema?
Por ejemplo:
public class SuperClass {
private final int id;
public SuperClass(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
public final class SubClass extends SuperClass {
private final String name;
public SubClass(int id, String code) {
super(id);
this.name = getId() + code; // Spotbugs reporta esta línea como un error
}
public final String getName() {
return name;
}
}
Reportes:
[ERROR] Low: Overridable method getId is called from constructor new SubClass(int, String).
[SubClass] At SubClass.java:[line ?] MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR
Nota:
Desde la versión 4.5.0.0 del detector de errores de Spotbugs, se agregó el detector de errores FindOverridableMethodCall
(ver detalles):
MC: Se llama a un método sobreescrito desde un constructor
(MCOVERRIDABLEMETHODCALLIN_CONSTRUCTOR)Llamar a un método sobreescrito durante la creación de un objeto en un constructor puede resultar en el uso de datos no inicializados. También puede filtrar la referencia del objeto parcialmente construido. Solo los métodos estáticos, finales o privados deben ser invocados desde un constructor.
davy.ai
Este es un comportamiento esperado en Spotbugs desde la versión 4.5.0.0. El detector de errores
FindOverridableMethodCall
se agregó para detectar cuando se llama a un método sobrescribible desde un constructor. Esto se considera un error porque puede dar lugar al uso de datos no inicializados o filtrar la referencia del objeto parcialmente construido. Solo se deben invocar métodos estáticos, finales o privados desde un constructor. En el ejemplo proporcionado, la subclase finalSubClase
llama al método sobrescribiblegetId()
de la superclaseSuperClass
en su constructor. Por lo tanto, Spotbugs informa del errorMC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR
. Para evitar este problema, se recomienda llamar solo a métodos estáticos, finales o privados desde un constructor.