web-dev-qa-db-fra.com

Pourquoi ne puis-je pas faire référence à une méthode d'instance en appelant explicitement un constructeur?

Quelqu'un sait-il pourquoi vous pouvez référencer une méthode static dans la première ligne du constructeur à l'aide de this() ou super(), mais pas d'une méthode non statique?

Considérez le travail suivant:

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;
    }
}

Et l'exemple non fonctionnel suivant:

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;
    }
}
33
Koekiebox

Les méthodes non statiques sont des méthodes d'instance. Ceux-ci ne sont accessibles que dans l'instance existante, et l'instance n'existe pas encore lorsque vous êtes dans le constructeur (il est encore en construction).

Pourquoi c'est comme ça? Parce que les méthodes d'instance peuvent accéder à des champs d'instance (non statiques), qui peuvent avoir des valeurs différentes dans différentes instances, il est donc inutile d'appeler cette méthode sur autre chose qu'une instance finie existante.

16
amorfis

Voir le Spécification du langage Java 8.8.7.1 . Cela dit que 

Une instruction d'invocation de constructeur explicite dans un corps de constructeur ne peut faire référence à aucune variable d'instance, ni à aucune méthode d'instance ni à aucune classe interne déclarée dans cette classe ni dans aucune superclasse, ni utiliser this ou super dans une expression quelconque; sinon, une erreur de compilation survient.

En effet, vous ne pouvez pas appeler une méthode d'instance avant la création de l'instance. À propos, il est possible d'appeler une méthode d'instance plus tard dans le constructeur (bien que ce ne soit pas une solution pour vous).

12
Marc

Je pense que c'est parce que les variables d'instance finales ne sont pas encore définies (vous n'avez donc pas encore d'instance) et qu'une méthode d'instance pourrait en accéder une. Considérant que toute l'initialisation statique a été effectuée avant l'appel du constructeur.

Greetz, GHad

1
GHad

parce que lorsque vous appelez this ou super constructeur, votre objet n'est pas encore construit. (votre instance n'est pas encore complètement initialisée). appeler une méthode d'instance ne crée donc pas de scène.

1
mhshams

TestNotWorking n'est pas initialisé à ce stade. Le problème est le suivant: le premier constructeur (TestNotWorking (A aParam)) peut appeler super () (toujours en interne), ce qui signifie que vous appelleriez une méthode avant que le constructeur de la superclasse ne soit appelé. C'est illégal.

1
Thomas Mueller

Si une méthode est non statique, vous devez l'appeler sur un objet.

Dans le deuxième exemple, vous devez créer un objet de classe TestNotWorking et appeler getAFromB sur cet objet.

Quelque chose comme:

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