Pregunta ¿Por qué no puedo referirme a un método de instancia mientras invoco explícitamente un constructor?


¿Alguien sabe por qué puede hacer referencia a un static método en la primera línea del constructor utilizando this() o super(), pero no es un método no estático?

Considere el siguiente trabajo:

public class TestWorking{
    private A a = null;
    public TestWorking(A aParam){
       this.a = aParam;
    }

    public TestWorking(B bParam)
    {
        this(TestWorking.getAFromB(bParam));
    }

    //It works because its marked static.
    private static A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}

Y el siguiente ejemplo no funcional:

public class TestNotWorking{
    private A a = null;
    public TestNotWorking(A aParam){
       this.a = aParam;
    }

    public TestNotWorking(B bParam)
    {
        this(this.getAFromB(bParam));
    }

    //This does not work. WHY???
    private A getAFromB(B param){
        A a = new A();
        a.setName(param.getName());
        return a;
    }
}

32
2017-09-10 14:40


origen


Respuestas:


Los métodos no estáticos son métodos de instancia. Solo se puede acceder a este en la instancia existente, y la instancia aún no existe cuando estás en el constructor (todavía está en construcción).

¿Por qué es así? Debido a que los métodos de instancia pueden acceder a campos de instancia (no estáticos), que pueden tener valores diferentes en instancias diferentes, por lo que no tiene sentido llamar a dicho método en otra cosa que no sea la instancia existente y terminada.


16
2017-09-10 14:44



Ver el Especificación del lenguaje Java 8.8.7.1. Esto dice que

Una instrucción de invocación de constructor explícita en un cuerpo constructor no puede referirse a ninguna variable de instancia o método de instancia o clases internas declaradas en esta clase o cualquier superclase, o uso this o super en cualquier expresión; de lo contrario, se produce un error en tiempo de compilación.

Esto se debe a que no puede llamar a un método de instancia antes de que se cree la instancia. Por cierto, es posible llamar a un método de instancia más adelante en el constructor (aunque no es una solución para usted).


11
2017-09-10 14:52



Creo que se debe a que las variables de instancia final aún no están configuradas (por lo que aún no tienes ninguna instancia) y un método de instancia podría acceder a una. Mientras que toda la inicialización estática se ha realizado antes de la llamada al constructor.

Greetz, GHad


1
2017-09-10 14:45



porque cuando llamas a esto o a un súper en el constructor, tu objeto aún no está construido. (su instancia aún no se ha inicializado). así que llamar a un método de instancia no hace escena.


1
2017-09-10 14:45



TestNotWorking no se inicializa en ese punto. El problema es que el primer constructor (TestNotWorking (A aParam)) podría llamar a super () (internamente siempre lo hace), lo que significa que llamaría a un método antes de invocar al constructor de la superclase. Eso es ilegal.


1
2017-09-10 14:51



Si un método no es estático, debe llamarlo a un objeto.

En el segundo ejemplo, necesitarías crear un objeto de clase TestNotWorking y llama getAFromB en ese objeto.

Algo como:

object = new TestNotWorking();
object.getAFromB(bParam);

0
2017-09-10 14:46