web-dev-qa-db-fra.com

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

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 faire en sorte que mes méthodes reconnaissent mes variables de classe?

263
Greg

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 quel type. C'est parce que vous comparez ce que vous voyez avec la classe "voiture". La classe contient ce qui est similaire à toutes les voitures. Pensez-y comme un modèle ou une idée.

Dans le même temps, la voiture que vous voyez est une instance de la classe "voiture" car elle possède toutes les propriétés attendues: elle est pilotée par une personne, elle dispose d'un moteur, de 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 lui attribuer une couleur. Comme ces attributs sont 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 (telles que Integer.parseInt()). Pour les champs, il s’agit généralement de constantes (comme les types de voiture, c’est-à-dire quelque chose pour lequel 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 moteur d’exécution puisse réserver de la mémoire pour l’instance (sinon, différentes instances s’écraseraient, ce que vous ne voudriez 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 méthode main() crée une instance de la classe qu'elle contient (cela semble étrange, mais puisque main() est créée avec la classe au lieu de l'instance, elle peut le faire), puis appelle une méthode d'instance (run()).

262
Aaron Digulla

Les champs et les 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' b et une méthode statique c, et que vous créez une instance a de votre classe A , les appels à A.c() et a.b() sont valides. La méthode c() n'a aucune idée de quelle instance est connectée et 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 pouvez ressembler à ceci alors:

class Programm {

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

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

Le mot clé static modifie le cycle de vie d'une méthode ou d'une variable dans une classe. Une méthode ou une variable static est créée au moment du chargement d'une classe. Une méthode ou une variable qui n'est pas déclarée comme static est créée uniquement lorsque la classe est instanciée en tant qu'objet, par exemple à l'aide de l'opérateur new.

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

  1. le code source de la classe est écrit en créant un modèle, un motif ou un tampon qui peut ensuite être utilisé pour
  2. créer un objet avec l'opérateur new en utilisant la classe pour créer une instance de la classe en tant qu'objet réel, puis 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.

Pour avoir un point d'entrée initial pour une application, Java a adopté la convention voulant que le programme Java ait une classe contenant une méthode avec un nom convenu ou spécial. Cette méthode spéciale s'appelle main(). Étant donné que la méthode doit exister, que la classe contenant la méthode principale ait été instanciée ou non, la méthode main() doit être déclarée avec le modificateur static de sorte que dès que la classe est chargée, la méthode main() est disponible.

Le résultat est que lorsque vous démarrez votre application Java par une ligne de commande telle que Java helloworld, une série d'actions se produit. 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 classe helloworld appelée main(String [] args). cette méthode doit être static pour qu'elle existe même si la classe n'a pas é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 commence l'exécution à la méthode main().

Vous devez donc créer une instance de votre classe en tant qu’objet et accéder ensuite aux méthodes et aux variables de la classe qui n’ont pas été déclarées avec le modificateur static. Une fois que votre programme Java a démarré avec la fonction main(), vous pouvez utiliser toutes les variables ou méthodes ayant le modificateur de static car elles font partie de la classe en cours de chargement.

Toutefois, les variables et méthodes de la classe qui ne font pas partie de la méthode main() et qui ne possèdent pas le modificateur static 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 méthode main(). Après avoir créé l'objet, vous pouvez utiliser les variables et les méthodes de l'objet. Une tentative d'utilisation des variables et méthodes de la classe qui n'ont pas le modificateur static sans passer par un objet de la classe est interceptée par le compilateur Java lors de la compilation et marqué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
    }
}
42
Richard Chambers

Le principe de base est que les variables statiques ou les méthodes statiques sont au niveau de la classe. Les variables ou méthodes de niveau classe sont chargées avant les méthodes ou les variables d'instance. Et, évidemment, l'élément non chargé ne peut pas être utilisé. Ainsi, le compilateur Java ne laisse pas les tâches à traiter en cours d’exécution se résoudre au moment de la compilation. C'est pourquoi il vous donne une erreur. Les choses non statiques ne peuvent pas être référées depuis un contexte statique. Vous avez juste besoin de lire sur l'étendue au niveau de la classe, l'étendue au niveau de l'instance et l'étendue locale.

11
Ajay Bhojak

Analysons d'abord votre programme. Dans votre programme, votre première méthode est main(), et gardez-la à l'esprit qu'il s'agit de 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 est uniquement la méthode déclarée, qu'il s'agisse d'une méthode statique ou non statique. Donc, vous ne pouvez 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 le statique vous tue. (C'est peut-être en train de te tuer mais cela donne seulement vie à ton programme !!) D'abord, tu dois comprendre l'essentiel. * La méthode statique appelle uniquement la méthode statique et utilise uniquement la variable statique. * Les variables statiques ou les méthodes statiques ne dépendent d'aucune instance de cette classe. (Par exemple, si vous modifiez n'importe quel état de la variable statique, cela se reflétera dans tous les objets de la classe) * C'est pourquoi vous l'appelez comme une variable de classe ou une méthode de classe. Et il y a beaucoup plus sur le mot clé "statique". J'espère que maintenant vous avez l'idée. Commencez par modifier la portée de la variable et déclarez-la en tant que statique (pour pouvoir l'utiliser dans des méthodes statiques).

Et le conseil pour vous est: vous avez mal compris l’idée de la portée des variables et des fonctionnalités statiques. Ayez une idée claire à ce sujet.

11
Suseendran.P

Pour pouvoir y accéder à partir de vos méthodes statiques, elles 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 {
  ...
8
Nick Moore

Maintenant, vous pouvez ajouter/utiliser des instances 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();
  }
}
7

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. Encore une fois, les méthodes statiques n'appartiennent pas à une instance particulière. Ils ne peuvent accéder qu'aux variables statiques. Imaginez que vous appelez MyClass.myMethod () et que myMethod soit une méthode statique. Si vous utilisez des variables non statiques dans la méthode, comment diable pourrait-il savoir quelles variables utiliser? C'est pourquoi vous ne pouvez utiliser des méthodes statiques que des variables statiques. Je le répète, ils n'appartiennent à aucun cas particulier.

4
Petar Minchev
  • La première chose à faire est de connaître la différence entre une instance de 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é static est disponible dans le contexte de la classe plutôt que dans le contexte d'une instance de la classe.

  • En corollaire à 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 à l'aide du nom de classe, par exemple. MonProgramme7.main (...)
  • La durée de vie d'un champ/méthode statique est équivalente à la durée de vie de votre application

Par exemple. Dites, voiture a la couleur de la propriété et présente le comportement 'mouvement'. Un exemple de la voiture serait une coccinelle rouge Volkswagen 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

2
Everyone

Avant d'appeler une méthode ou une variable d'instance, un objet (instance) est nécessaire. Lorsque la variable d'instance est appelée depuis une méthode statique, le compilateur 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 à l'objet this. Cela signifie que la variable appartient à tout objet créé et que chaque objet possède sa propre copie de méthodes d'instance et de variables.

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

2
ultimatex

C’est un peu difficile d’expliquer la clé statique de Word pour tous les débutants.
Vous apprendrez à le savoir clairement en travaillant davantage avec les classes et les objets.

| * | Statique: Les éléments statiques peuvent être appelés avec un 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 la clé statique Word avant eux.

| * | Non statique:Les éléments non statiques peuvent être appelés avec la variable de classe
Si ce n'est pas statique, vous avez besoin d'une variable de la classe,
mettre le point après la variable de classe et
appelle ensuite la fonction.

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

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

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);
        }
    }
}
1
Sujay U N

Il est de la responsabilité de 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’existe pas de variable membre b, c.Mais pourquoi ???. OK Lest's see. Ici, b, c sont des variables d'instance. Depuis variable d'instance, la mémoire est obtenue au moment de la création de l'objet. Donc, ici b, c ne reçoivent pas encore de mémoire. C'est pourquoi il n'y a pas d'existence de b, c. Donc, il n'y a qu'une existence d'un. Pour ClassLoader, il ne dispose que d’une information sur a. ClassLoader n'a pas encore reconnu 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 code, le compilateur donnera une erreur CE. CE: la méthode non statique display () ne peut pas être référencée depuis un contexte statique.

Maintenant, pour ClassLoader, il 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 () à la compilation. Une erreur de compilation a eu lieu.

0
Newaz Sharif Amit