tipos sobrecarga metodos metodo ejercicios ejemplos destructores constructores java methods constructor virtual abstract

sobrecarga - ¿Está bien llamar método abstracto desde un constructor en Java?



sobrecarga de metodos en java (4)

Es una muy mala práctica llamar a un método abstracto de un constructor. Los métodos llamados de los constructores siempre deben ser privados o finales, para evitar la anulación.

Vea este enlace a una pregunta aquí

Esta pregunta ya tiene una respuesta aquí:

Supongamos que tengo una clase base abstracta que implementa la interfaz Runnable.

public abstract class Base implements Runnable { protected int param; public Base(final int param) { System.out.println("Base constructor"); this.param = param; // I''m using this param here new Thread(this).start(); System.out.println("Derivative thread created with param " + param); } @Override abstract public void run(); }

Y aquí está una de las pocas clases derivadas.

public class Derivative extends Base { public Derivative(final int param) { super(param); } @Override public void run() { System.out.println("Derivative is running with param " + param); } public static void main(String[] args) { Derivative thread = new Derivative(1); } }

El punto es que quiero que mi clase Base haga cosas generales en lugar de copiarlas cada vez. En realidad, está funcionando bien, la salida es siempre la misma:

Constructor base El subproceso derivado creado con param 1 Derivado se ejecuta con param 1

Pero, ¿es seguro IN JAVA iniciar un hilo que llame al método abstracto en el constructor? Porque, en C ++ y C # es inseguro en la mayoría de los casos, que yo sepa. ¡Gracias!


Este código demuestra por qué nunca debe llamar un método abstracto, o cualquier otro método reemplazable, desde un constructor:

abstract class Super { Super() { doSubStuff(); } abstract void doSubStuff(); } class Sub extends Super { String s = "Hello world"; void doSubStuff() { System.out.println(s); } } public static void main(String[] args) { new Sub(); }

Cuando se ejecuta, esto imprime null . Esto significa que los únicos métodos "seguros" que tiene un constructor son privados y / o finales.

Por otro lado, su código no llama realmente un método abstracto de un constructor. En su lugar, pasa un objeto sin inicializar a otro subproceso para su procesamiento, lo que es peor, ya que se le puede dar prioridad y ejecutar al subproceso que está iniciando antes de que su Base finalice su inicialización.


No es una buena idea ya que cuando se invoca run (), es posible que el objeto Derivado no se haya inicializado. Si run () depende de cualquier estado en Derivado, puede fallar.

En tu caso simple funciona. Pero entonces no hay ningún punto para la subclase. Usted puede simplemente

public Base(final int param, Runnable action) { new Thread(action).start();


Pasar this fuera del constructor se llama "dejar que this escape se escape del constructor", y puede llevar a algunos errores particularmente desagradables y extraños, porque el objeto puede estar en un estado inconsistente.

Este es especialmente el caso cuando se pasa a otro hilo, como en este ejemplo. Debido al derecho de las JVM a reordenar las declaraciones dentro de un hilo, puede obtener un comportamiento / estado indefinido.