La variable non statique ne peut pas être référencée à partir d'un contexte statique

288

J'ai écrit ce code de test:

class MyProgram
{
    int count = 0;
    public static void main(String[] args)
    {
        System.out.println(count);
    }
}

Mais cela donne l'erreur suivante:

Main.java:6: error: non-static variable count cannot be referenced from a static context
        System.out.println(count);
                           ^

Comment puis-je obtenir mes méthodes pour reconnaître mes variables de classe?

Greg
la source
Essayez d'éviter d'utiliser de l'électricité statique autant que possible. Vous pouvez écrire un programme complet, tout statique, comme dans C. Mais ce ne sera pas très bon. Essayez d'utiliser Java comme il est censé être utilisé, en tant que langage orienté objet.
Erick G.Hagstrom du

Réponses:

294

Vous devez comprendre la différence entre une classe et une instance de cette classe. Si vous voyez une voiture dans la rue, vous savez immédiatement que c'est une voiture même si vous ne pouvez pas voir quel modèle ou type. C'est parce que vous comparez ce que vous voyez avec la classe "voiture". La classe contient qui est similaire à toutes les voitures. Considérez-le comme un modèle ou une idée.

En même temps, la voiture que vous voyez est une instance de la classe "voiture" car elle a toutes les propriétés que vous attendez: il y a quelqu'un qui la conduit, elle a un moteur, des roues.

Donc, la classe dit "toutes les voitures ont une couleur" et l'instance dit "cette voiture spécifique est rouge".

Dans le monde OO, vous définissez la classe et à l'intérieur de la classe, vous définissez un champ de type Color. Lorsque la classe est instanciée (lorsque vous créez une instance spécifique), la mémoire est réservée à la couleur et vous pouvez attribuer une couleur à cette instance spécifique. Ces attributs étant spécifiques, ils ne sont pas statiques.

Les champs et méthodes statiques sont partagés avec toutes les instances. Ils concernent des valeurs spécifiques à la classe et non une instance spécifique. Pour les méthodes, il s'agit généralement de méthodes d'assistance globales (comme Integer.parseInt()). Pour les champs, ce sont généralement des constantes (comme les types de voitures, c'est-à-dire quelque chose où vous avez un ensemble limité qui ne change pas souvent).

Pour résoudre votre problème, vous devez instancier une instance (créer un objet) de votre classe afin que le runtime puisse réserver de la mémoire pour l'instance (sinon, différentes instances se remplaceraient mutuellement, ce que vous ne voulez pas).

Dans votre cas, essayez ce code comme bloc de départ:

public static void main (String[] args)
{
    try
    {
        MyProgram7 obj = new MyProgram7 ();
        obj.run (args);
    }
    catch (Exception e)
    {
        e.printStackTrace ();
    }
}

// instance variables here

public void run (String[] args) throws Exception
{
    // put your code here
}

La nouvelle main()méthode crée une instance de la classe qu'elle contient (cela semble étrange mais puisqu'elle main()est créée avec la classe plutôt qu'avec l'instance, elle peut le faire), puis appelle une méthode d'instance ( run()).

Aaron Digulla
la source
J'explique cela en ce moment à notre nouveau collègue - merci pour cette excellente explication. Cela devrait répondre à l'acceptet.
Supahupe
83

Les champs et méthodes statiques sont connectés à la classe elle-même et non à ses instances. Si vous avez une classe A, une méthode «normale» bet une méthode statique cet que vous créez une instance ade votre classe A, les appels à A.c()et a.b()sont valides. La méthode c()n'a aucune idée de l'instance connectée, elle ne peut donc pas utiliser de champs non statiques.

La solution pour vous est de rendre vos champs statiques ou vos méthodes non statiques. Vous pourriez alors ressembler à ceci:

class Programm {

    public static void main(String[] args) {
        Programm programm = new Programm();
        programm.start();
    }

    public void start() {
        // can now access non-static fields
    }
}
Mnementh
la source
54

Le staticmot-clé modifie le cycle de vie d'une méthode ou d'une variable au sein d'une classe. Une staticméthode ou une variable est créée au moment du chargement d'une classe. Une méthode ou une variable qui n'est pas déclarée comme staticest créée uniquement lorsque la classe est instanciée en tant qu'objet, par exemple en utilisant l' newopérateur.

Le cycle de vie d'une classe, en termes généraux, est le suivant:

  1. le code source de la classe est écrit en créant un modèle ou un modèle ou un tampon qui peut ensuite être utilisé pour
  2. créer un objet avec l' newopérateur en utilisant la classe pour créer une instance de la classe en tant qu'objet réel, puis une fois terminé avec l'objet
  3. détruisez l'objet en récupérant les ressources qu'il détient telles que la mémoire lors de la récupération de place.

Afin d'avoir un point d'entrée initial pour une application, Java a adopté la convention selon laquelle le programme Java doit avoir une classe qui contient une méthode avec un nom convenu ou spécial. Cette méthode spéciale est appelée main(). Puisque la méthode doit exister, que la classe contenant la méthode principale ait été instanciée ou non, la main()méthode doit être déclarée avec le staticmodificateur pour que dès que la classe est chargée, la main()méthode est disponible.

Le résultat est que lorsque vous démarrez votre application Java par une ligne de commande telle qu'une java helloworldsérie d'actions se produisent. Tout d'abord, une machine virtuelle Java est démarrée et initialisée. Ensuite, le fichier helloworld.class contenant le code Java compilé est chargé dans la machine virtuelle Java. Ensuite, la machine virtuelle Java recherche une méthode dans la helloworldclasse appelée main(String [] args). cette méthode doit être statictelle qu'elle existera même si la classe n'a pas réellement été instanciée en tant qu'objet. La machine virtuelle Java ne crée pas d'instance de la classe en créant un objet à partir de la classe. Il charge simplement la classe et démarre l'exécution à la main()méthode.

Vous devez donc créer une instance de votre classe en tant qu'objet, puis vous pouvez accéder aux méthodes et variables de la classe qui n'ont pas été déclarées avec le staticmodificateur. Une fois que votre programme Java a commencé avec la main()fonction, vous pouvez ensuite utiliser toutes les variables ou méthodes qui ont le modificateur staticcar elles existent dans le cadre de la classe en cours de chargement.

Cependant, les variables et méthodes de la classe qui sont en dehors de la main()méthode et qui n'ont pas le staticmodificateur ne peuvent pas être utilisées tant qu'une instance de la classe n'a pas été créée en tant qu'objet dans la main()méthode. Après avoir créé l'objet, vous pouvez ensuite utiliser les variables et les méthodes de l'objet. Une tentative d'utilisation des variables et des méthodes de la classe qui n'ont pas le staticmodificateur sans passer par un objet de la classe est interceptée par le compilateur Java au moment de la compilation et signalée comme une erreur.

import java.io.*;

class HelloWorld {
    int myInt;      // this is a class variable that is unique to each object
    static int myInt2;  // this is a class variable shared by all objects of this class

    static void main (String [] args) {
        // this is the main entry point for this Java application
        System.out.println ("Hello, World\n");
        myInt2 = 14;    // able to access the static int
        HelloWorld myWorld = new HelloWorld();
        myWorld.myInt = 32;   // able to access non-static through an object
    }
}
Richard Chambers
la source
11

Analysons d'abord votre programme. Dans votre programme, votre première méthode est main(), et gardez à l'esprit que c'est la méthode statique ... Ensuite, vous déclarez la variable locale pour cette méthode (compareCount, low, high, etc.). La portée de cette variable n'est que la méthode déclarée, qu'elle soit statique ou non statique. Vous ne pouvez donc pas utiliser ces variables en dehors de cette méthode. C'est l'erreur de base que vous avez commise.

Ensuite, nous arrivons au point suivant. Vous avez dit que l'électricité statique vous tuait. (Cela peut vous tuer, mais cela ne fait que donner vie à votre programme !!) Vous devez d'abord comprendre l'essentiel. * La méthode statique appelle uniquement la méthode statique et utilise uniquement la variable statique. * La variable statique ou la méthode statique ne dépendent d'aucune instance de cette classe. (c'est-à-dire que si vous changez un état de la variable statique, il se reflétera dans tous les objets de la classe) * Pour cette raison, vous l'appelez comme variable de classe ou méthode de classe. Et il y en a beaucoup plus sur le mot-clé "statique". J'espère que vous avez maintenant l'idée. Modifiez d'abord la portée de la variable et déclarez-la comme statique (pour pouvoir l'utiliser dans des méthodes statiques).

Et le conseil pour vous est: vous avez mal compris l'idée de l'étendue des variables et des fonctionnalités statiques. Obtenez une idée claire à ce sujet.

Suseendran.P
la source
11

La chose très fondamentale est que les variables statiques ou les méthodes statiques sont au niveau de la classe. Les variables ou méthodes au niveau de la classe sont chargées avant les méthodes ou les variables au niveau de l'instance. Et évidemment, la chose qui n'est pas chargée ne peut pas être utilisée. Ainsi, le compilateur java ne laissant pas les choses à gérer au moment de l'exécution se résout au moment de la compilation. C'est pourquoi il vous donne des erreurs non statiques, les choses ne peuvent pas être référencées à partir d'un contexte statique. Il vous suffit de lire la portée de niveau de classe, la portée de niveau d'instance et la portée locale.

Ajay Bhojak
la source
8

Pour pouvoir y accéder à partir de vos méthodes statiques, ils doivent être des variables membres statiques, comme ceci:

public class MyProgram7 {
  static Scanner scan = new Scanner(System.in);
  static int compareCount = 0;
  static int low = 0;
  static int high = 0;
  static int mid = 0;  
  static int key = 0;  
  static Scanner temp;  
  static int[]list;  
  static String menu, outputString;  
  static int option = 1;  
  static boolean found = false;

  public static void main (String[]args) throws IOException {
  ...
Nick Moore
la source
7

Vous pouvez maintenant ajouter / utiliser des instances avec dans la méthode

public class Myprogram7 {

  Scanner scan;
  int compareCount = 0;
  int low = 0;
  int high = 0;
  int mid = 0;  
  int key = 0;  
  Scanner temp;  
  int[]list;  
  String menu, outputString;  
  int option = 1;  
  boolean found = false;  

  private void readLine() {

  }

  private void findkey() {

  }

  private void printCount() {

  }
  public static void main(String[] args){

    Myprogram7 myprg=new Myprogram7();
    myprg.readLine();
    myprg.findkey();
    myprg.printCount();
  }
}
Sainath Patwary karnate
la source
Exemple très solide que j'ai utilisé comme modèle pour réviser un fichier src complexe dans une structure appropriée.
XMAN
3

Je vais essayer de vous expliquer la chose statique. Tout d'abord, les variables statiques n'appartiennent à aucune instance particulière de la classe. Ils sont reconnus avec le nom de la classe. Les méthodes statiques n'appartiennent à nouveau à aucune instance particulière. Ils ne peuvent accéder qu'aux variables statiques. Imaginez que vous appelez MyClass.myMethod () et myMethod est une méthode statique. Si vous utilisez des variables non statiques à l'intérieur de la méthode, comment diable saurait-il quelles variables utiliser? C'est pourquoi vous ne pouvez utiliser à partir de méthodes statiques que des variables statiques. Je répète encore une fois qu'ils n'appartiennent à aucune instance particulière.

Petar Minchev
la source
2
  • La première chose est de connaître la différence entre une instance d'une classe et la classe elle-même. Une classe modélise certaines propriétés et le comportement de l'ensemble dans le contexte de ces propriétés. Une instance définira des valeurs spécifiques pour ces propriétés.

  • Tout ce qui est lié au mot clé statique est disponible dans le contexte de la classe plutôt que dans le contexte d'une instance de la classe

  • En corollaire de ce qui précède

    1. les variables d'une méthode ne peuvent pas être statiques
    2. les champs statiques et les méthodes doivent être appelés en utilisant le nom de classe, par exemple MyProgram7.main (...)
  • La durée de vie d'un champ / d'une méthode statique est équivalente à la durée de vie de votre application

Par exemple, la voiture a la couleur de la propriété et présente le comportement «mouvement». Un exemple de la voiture serait une Volkswagen Beetle rouge en mouvement à 25 km / h.

Maintenant, une propriété statique de la voiture serait le nombre de roues (4) sur la route, et cela s'appliquerait à toutes les voitures.

HTH

Toutes les personnes
la source
1

Il est chargé par ClassLoader de charger les fichiers de classe. Voyons ce qui se passe lorsque nous écrivons nos propres classes.

Exemple 1:

class StaticTest {

      static int a;
      int b;
      int c;
}

Maintenant, nous pouvons voir que la classe "StaticTest" a 3 champs. Mais en réalité il n'y a pas d'existence de variable membre b, c. Mais pourquoi ???. OK, Lest voit. Ici b, c sont une variable d'instance, car la variable d'instance obtient la mémoire au moment de la création de l'objet. Donc ici b, c n'ont pas encore de mémoire. C'est pourquoi il n'y a pas d'existence de b, c. Il n'y a donc que l'existence d'un. Pour ClassLoader, il ne contient qu'une seule information sur a. ClassLoader ne reconnaît pas encore b, c car son objet n'est pas encore instancié.

Voyons un autre exemple: Exemple 2:

class StaticTest {

      public void display() {
          System.out.println("Static Test");
      }


      public static void main(String []cmd) {

             display();       
      }

}

Maintenant, si nous essayons de compiler ce compilateur de code donnera une erreur CE. CE: la méthode non statique display () ne peut pas être référencée à partir d'un contexte statique.

Maintenant, pour ClassLoader, cela ressemble à:

class StaticTest {

      public static void main(String []cmd) {

             display();       
      }

}

Dans l'exemple 2, l'erreur CE est due au fait que nous appelons une méthode non statique à partir d'un contexte statique. Il n'est donc pas possible pour ClassLoader de reconnaître la méthode display () au moment de la compilation. Une erreur au moment de la compilation s'est donc produite.

Newaz Sharif Amit
la source
Vous avez probablement soumis votre réponse par accident avant d'avoir réussi à la terminer? Veuillez l'éditer et ajouter le contenu manquant, merci!
plamut
1

Avant d'appeler une méthode d'instance ou une variable d'instance Il a besoin d'un objet (instance). Lorsque la variable d'instance est appelée à partir du compilateur de méthode statique, elle ne sait pas à quel objet appartient cette variable. Parce que les méthodes statiques n'ont pas d'objet (une seule copie toujours). Lorsque vous appelez une variable d'instance ou des méthodes d'instance à partir d'une méthode d'instance, il fait référence authis objet. Cela signifie que la variable appartient à tout objet créé et que chaque objet possède sa propre copie des méthodes et variables d'instance.

Les variables statiques sont marquées comme staticet les variables d'instance n'ont pas de mot-clé spécifique.

Ultimatex
la source
0

C'est un peu différent pour expliquer le mot clé statique pour tous les débutants.
Vous le saurez clairement lorsque vous travaillerez davantage avec les classes et les objets.

| * | Statique: les éléments statiques peuvent être appelés avec le nom de classe
Si vous observez dans les codes, certaines fonctions sont directement appelées avec des noms de classe comme

NamCls.NamFnc();

System.out.println();

Cela est dû au fait que NamFnc et println seront déclarés en utilisant le mot clé static avant eux.

| * | Non statique: les éléments non statiques peuvent être appelés avec une variable de classe
Si ce n'est pas statique, vous avez besoin d'une variable de la classe,
placez un point après la variable de classe,
puis appelez la fonction.

NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();


Le code ci-dessous vous explique clairement

| * | Fonction statique et non statique en classe:

public class NamCls
{
    public static void main(String[] args)
    {
        PlsPrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamObjVar.PrnFnc("Tst Txt");
    }

    static void PlsPrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }

    void PrnFnc(String SrgPsgVal)
    {
        System.out.println(SrgPsgVal);
    }
}


| * | Classe statique et non statique à l'intérieur d'une classe:

public class NamCls
{
    public static void main(String[] args)
    {
        NamTicCls NamTicVaj = new NamTicCls();
        NamTicVaj.PrnFnc("Tst Txt");

        NamCls NamObjVar = new NamCls();
        NamNicCls NamNicVar = NamObjVar.new NamNicCls();
        NamNicVar.PrnFnc("Tst Txt");
    }

    static class NamTicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }

    class NamNicCls
    {
        void PrnFnc(String SrgPsgVal)
        {
            System.out.println(SrgPsgVal);
        }
    }
}
Sujay UN
la source