sobrecarga - tipos de constructores en java




¿Está bien llamar método abstracto desde un constructor en Java? (3)

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.


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.





abstract