web-dev-qa-db-fra.com

Quelle est la raison derrière "la méthode non statique ne peut pas être référencée à partir d'un contexte statique"?

L'erreur très courante chez les débutants est d'utiliser une propriété de classe "statiquement" sans créer d'instance de cette classe. Il vous laisse avec le message d'erreur mentionné:

Vous pouvez soit rendre la méthode non statique statique, soit créer une instance de cette classe pour qu'elle utilise ses propriétés.

Pourquoi? Je ne demande pas de solutions. Je serais reconnaissant de savoir quelle est la raison derrière cela. La raison principale!

private Java.util.List<String> someMethod(){
    /* Some Code */
    return someList;            
}

public static void main(String[] strArgs){          
     // The following statement causes the error. You know why..
    Java.util.List<String> someList = someMethod();         
}
242
DragonBorn

Vous ne pouvez pas appeler quelque chose qui n'existe pas. Puisque vous n'avez pas créé d'objet, la méthode non statique n'existe pas encore. Une méthode statique (par définition) existe toujours.

338
Brian Knoblauch

La méthode que vous essayez d'appeler est une méthode de niveau instance. vous n'avez pas d'instance.

Les méthodes static appartiennent à la classe, les méthodes non -static appartiennent à des instances de la classe.

57
Steven A. Lowe

L'essence de la programmation orientée objet consiste à encapsuler la logique avec les données sur lesquelles elle opère.

Les méthodes d'instance sont la logique, les champs d'instance sont les données. Ensemble, ils forment un objet.

public class Foo
{
    private String foo;
    public Foo(String foo){ this.foo = foo; }
    public getFoo(){ return this.foo; }

    public static void main(String[] args){
        System.out.println( getFoo() );
    }
}

Quel pourrait être le résultat de l'exécution du programme ci-dessus?

Sans objet, il n'y a pas de données d'instance et, bien que les méthodes d'instance fassent partie de la définition de classe, elles ont besoin d'une instance d'objet pour leur fournir des données.

En théorie, une méthode d'instance qui n'accède à aucune donnée d'instance pourrait fonctionner dans un contexte statique, mais il n'y a alors aucune raison pour que ce soit une méthode d'instance. C'est une décision de conception linguistique de le permettre de toute façon plutôt que de créer une règle supplémentaire pour l'interdire.

23
Michael Borgwardt

Je viens de me rendre compte que les gens ne devraient pas être exposés très tôt au concept de "statique".

Les méthodes statiques devraient probablement être l'exception plutôt que la norme. Surtout tôt si vous voulez apprendre la POO. (Pourquoi commencer par une exception à la règle?) C'est très contre-pédagogique de Java, que la "première" chose à apprendre est le public statique vide. (Peu de vraies applications Java ont de toute façon leurs propres méthodes principales.)

12
Hugo

Je pense qu’il est intéressant de souligner que, selon les règles du langage Java, le compilateur Java insère l’équivalent de "this". lorsqu'il constate que vous accédez à des méthodes d'instance ou à des champs d'instance sans instance explicite. Bien sûr, le compilateur sait qu'il ne peut le faire que depuis une méthode d'instance, qui a une variable "this", contrairement aux méthodes statiques.

Ce qui signifie que lorsque vous utilisez une méthode d'instance, les éléments suivants sont équivalents:

instanceMethod();
this.instanceMethod();

et ceux-ci sont également équivalents:

... = instanceField;
... = this.instanceField;

Le compilateur insère effectivement le "this". lorsque vous ne fournissez pas une instance spécifique.

Ce bit d'aide magique du compilateur peut confondre les novices: cela signifie que les appels d'instance et les appels statiques semblent parfois avoir la même syntaxe alors qu'il s'agit en réalité d'appels de types différents et de mécanismes sous-jacents.

L'appel à une méthode d'instance est parfois appelé invocation ou dispatch de méthode en raison des comportements des méthodes virtuelles prenant en charge le polymorphisme; Le comportement de dispatching se produit que vous écriviez une instance d'objet explicite ou que le compilateur insère un "this.".

Le mécanisme d'appel de méthode statique est plus simple, comme un appel de fonction dans un langage non-POO.

Personnellement, je pense que le message d'erreur est trompeur, il pourrait indiquer "une méthode non statique ne peut pas être référencée à partir d'un contexte statique sans spécifier une instance d'objet explicite".


Le compilateur se plaint de ne pas pouvoir simplement insérer le "ceci" standard. comme dans les méthodes d'instance, parce que ce code est dans une méthode statique; cependant, l'auteur a peut-être simplement oublié de fournir l'instance d'intérêt pour cette invocation - par exemple, une instance éventuellement fournie à la méthode statique en tant que paramètre ou créée au sein de cette méthode statique.

En bref, vous pouvez très certainement appeler des méthodes d'instance à partir d'une méthode statique. Il vous suffit simplement d'avoir et de spécifier un objet d'instance explicite pour l'appel.

11
Erik Eidt

Les réponses à ce jour décrivent pourquoi, mais voici une autre chose à considérer:

Vous pouvez appeler une méthode depuis une classe instanciable en ajoutant un appel de méthode à son constructeur,

Object instance = new Constuctor().methodCall();

ou

primitive name = new Constuctor().methodCall();

Ceci est utile si vous souhaitez uniquement utiliser une méthode d'une classe instanciable une fois dans une même portée. Si vous appelez plusieurs méthodes à partir d'une classe instanciable dans une seule et même étendue, créez définitivement une instance référencable.

6
Ande TURNER

Si nous essayons d'accéder à une méthode d'instance à partir d'un contexte statique, le compilateur n'a aucun moyen de deviner à quelle méthode d'instance (variable pour quel objet) vous faites référence. Cependant, vous pouvez toujours y accéder en utilisant une référence d'objet.

3
Vivek Vermani

Une méthode statique associe une action à un type d'objet, tandis que la méthode non statique associe une action à une instance de ce type d'objet. Typiquement, c'est une méthode qui fait quelque chose en relation avec l'instance.

Ex:

class car pourrait avoir une méthode de lavage, qui indiquerait le lavage d’une voiture particulière, alors qu’une méthode statique s’appliquerait au type de voiture.

2
Robin

si une méthode n'est pas statique, cela "indique" au compilateur que la méthode nécessite l'accès aux données au niveau instance de la classe (comme un champ non statique). Ces données ne seraient disponibles que si une instance de la classe avait été créée. Le compilateur renvoie donc une erreur si vous essayez d'appeler la méthode à partir d'une méthode statique. Si en fait la méthode ne fait PAS référence à un membre non statique de la classe, rendez la méthode statique.

Dans Resharper, par exemple, le simple fait de créer une méthode non statique qui NE référence PAS un membre statique de la classe génère un message d'avertissement "Cette méthode peut être rendue statique".

2
Charles Bretana

Le compilateur ajoute en fait un argument aux méthodes non statiques. Il ajoute un this pointer/reference. This is also the reason why a static method can not use this, car il n'y a pas d'objet.

2
antiparagon

Vous demandez donc une raison essentielle?

Étant donné que vous développez en Java, le compilateur génère un code objet que la machine virtuelle Java peut interpréter. De toute façon, la machine virtuelle Java est un programme binaire qui s’exécute en langage machine (la version de la machine virtuelle spécifique à votre système d’exploitation et à votre matériel a déjà été compilée par un autre langage de programmation tel que C afin d’obtenir un code machine pouvant être exécuté dans votre processeur). À la fin, tout code est traduit en code machine. Ainsi, créer un objet (une instance d'une classe) équivaut à réserver un espace mémoire (des registres de mémoire qui seront des registres de processeur lorsque le planificateur CPU du système d'exploitation place votre programme en haut de la file d'attente pour l'exécuter). d'avoir un lieu de stockage de données capable de lire et d'écrire des données. Si vous n'avez pas d'instance de classe (ce qui se produit dans un contexte statique), vous ne disposez pas de cet espace mémoire pour lire ou écrire les données. En fait, comme d’autres personnes l’ont dit, les données n’existent pas (car, depuis le début, vous n’avez jamais écrit ni réservé l’espace mémoire pour le stocker).

Désolé pour mon anglais! Je suis latin!

0
Cristián Munizaga

La raison simple derrière ceci est que les membres de données statiques de la classe parente peuvent être accédés (uniquement s'ils ne sont pas remplacés) mais que, par exemple, les membres de données ou les méthodes (non statiques) ont besoin de leur référence et ne peuvent donc être appelées qu'à travers un objet. .

0
Vipul

Une méthode non statique dépend de l'objet. Il est reconnu par le programme une fois l'objet créé.

Les méthodes statiques peuvent être appelées même avant la création d'un objet. Les méthodes statiques sont idéales pour effectuer des comparaisons ou des opérations qui ne dépendent pas des objets avec lesquels vous prévoyez de travailler.

0
Ejesalva