Question

Pour être précis, j'essayais ce code:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

Mais cela a donné l'erreur

  

Impossible d'accéder à un champ non statique dans la méthode statique main

J'ai donc changé la déclaration de horloge en ceci:

static Clock clock = new Clock();

Et cela a fonctionné. Qu'est-ce que cela signifie de mettre ce mot clé avant la déclaration? Que fera-t-il et / ou limitera-t-il exactement à ce qui peut être fait pour cet objet?

Était-ce utile?

La solution

Les membres

static appartiennent à la classe et non à une instance spécifique.

Cela signifie qu'il n'existe qu'une seule instance d'un champ statique [1] même si vous créez un million d'instances de la classe ou vous n'en créez pas. Il sera partagé par toutes les instances.

Comme les méthodes static n'appartiennent pas non plus à une instance spécifique, elles ne peuvent pas faire référence à des membres d'instance. Dans l'exemple donné, main ne sait pas à quelle instance de la classe Hello (et donc à quelle instance de la classe Clock ) il devrait faire référence. . Les membres static ne peuvent faire référence qu'aux membres static . Les membres d'instance peuvent bien sûr accéder aux membres static .

Remarque secondaire: Bien entendu, les membres de static peuvent accéder aux membres de l'instance via une référence d'objet .

Exemple:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1]: selon les caractéristiques d'exécution, il peut s'agir d'un par ClassLoader ou AppDomain ou d'un thread, mais cela se situe à côté du point.

Autres conseils

Cela signifie qu'il n'y a qu'une seule instance de " horloge " dans Hello, pas un par chaque instance distincte du message "Hello". classe, ou plus encore, cela signifie qu’il y aura une "horloge" communément partagée. référence parmi toutes les occurrences du message "Bonjour". classe.

Donc, si vous deviez faire un "nouveau Bonjour" n'importe où dans votre code: A- dans le premier scénario (avant le changement, sans utiliser "statique"), cela créerait une nouvelle horloge à chaque fois qu'un "nouveau Bonjour" est appelé, mais B- dans le deuxième scénario (après le changement, en utilisant "statique"), chaque "nouveau Bonjour". Cette instance partagerait et utiliserait toujours la même et initiale "horloge". référence créée en premier.

Sauf si vous aviez besoin de " horloge " quelque part en dehors de la rue principale, cela fonctionnerait aussi bien:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}

Le mot clé static signifie que quelque chose (un champ, une méthode ou une classe imbriquée) est lié au type plutôt qu'à une instance particulière de le type. Ainsi, par exemple, on appelle Math.sin (...) sans aucune instance de la classe Math , et en effet vous ne pouvez pas créer une instance de la classe Math .

Pour plus d'informations, voir le extrait pertinent du didacticiel Java d'Oracle .

Sidenote

Malheureusement, Java, vous permet d'accéder aux membres statiques comme s'ils étaient des membres d'instance, par exemple.

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

Cela donne l'apparence comme si sleep est une méthode d'instance, mais c'est en fait une méthode statique - toujours rend le thread actuel en veille. . Il est préférable d’expliquer clairement ce code dans le code appelant:

// Clearer
Thread.sleep(5000);

Le mot clé static en Java signifie que la variable ou la fonction est partagée entre toutes les instances de cette classe, car elle appartient au type , et non aux objets eux-mêmes.

Donc, si vous avez une variable: private statique int i = 0; et que vous l'incrémentez ( i ++ ) dans un cas, le changement sera répercuté dans tous les cas. . i sera désormais égal à 1 dans toutes les instances.

Les méthodes statiques peuvent être utilisées sans instancier un objet.

Utilisation de base des membres statiques ...

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}

C'est ainsi que vous pouvez avoir des valeurs partagées dans tous les membres de la classe sans envoyer l'instance de classe Hello à une autre classe. Et en statique, vous n'avez pas besoin de créer une instance de classe.

Hello hello = new Hello();
hello.staticValue = "abc";

Vous pouvez simplement appeler des valeurs statiques ou des méthodes par nom de classe:

Hello.staticValue = "abc";

Static in Java:

Statique est un modificateur de non accès. Le mot clé static appartient à la classe plutôt qu'à l'instance de la classe. peut être utilisé pour attacher une variable ou une méthode à une classe.

Le mot clé statique PEUT être utilisé avec:

Méthode

Variable

Classe imbriquée dans une autre classe

Bloc d'initialisation

NE PEUT PAS être utilisé avec:

Classe (non imbriquée)

Constructeur

Interfaces

Méthode Local Inner Class (Différence puis classe imbriquée)

Méthodes de classe interne

Variables d'instance

Variables locales

Exemple:

Imaginons l'exemple suivant qui contient une variable d'instance nommée count qui est incrémentée dans le constructeur:

package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

Résultat:

  

1 1 1

Etant donné que la variable d'instance obtient la mémoire au moment de la création de l'objet, chaque objet aura la copie de la variable d'instance. Si elle est incrémentée, elle ne sera pas répercutée sur les autres objets.

Maintenant, si nous changeons le nombre de variables d'instance en un nombre statique , le programme produira un résultat différent:

package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}

Résultat:

  

1 2 3

Dans ce cas, la variable statique obtiendra la mémoire une seule fois. Si un objet modifie la valeur de la variable statique, il conservera sa valeur.

Statique avec finale:

La variable globale déclarée comme final et static reste inchangée pour l'ensemble de l'exécution. En effet, les membres statiques sont stockés dans la mémoire de classe et ne sont chargés qu'une seule fois dans toute l'exécution. Ils sont communs à tous les objets de la classe. Si vous déclarez des variables statiques comme définitives, aucun des objets ne peut pas changer leur valeur car elle est définitive. Par conséquent, les variables déclarées finales et statiques sont parfois appelées constantes. Tous les champs d'interface sont appelés constantes, car ils sont finaux et statiques par défaut.

 entrez la description de l'image ici

Ressource Image: Static final

Statique signifie qu'il n'est pas nécessaire de créer une instance de la classe pour utiliser les méthodes ou les variables associées à la classe. Dans votre exemple, vous pouvez appeler:

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class

directement, au lieu de:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

De l'intérieur d'une méthode statique (qui appartient à une classe), vous ne pouvez accéder à aucun membre non statique, car leurs valeurs dépendent de votre instanciation de la classe. Un objet Clock non statique, qui est un membre d'instance, aurait une valeur / référence différente pour chaque instance de votre classe Hello. Par conséquent, vous ne pouvez pas y accéder depuis la partie statique de la classe.

Cette discussion a jusqu'à présent ignoré les considérations relatives au chargeur de classes. Strictement parlant, les champs statiques Java sont partagés entre toutes les instances d'une classe pour un chargeur de classe donné.

Pour ajouter aux réponses existantes, laissez-moi essayer avec une image:

Un taux d'intérêt de 2% est appliqué à TOUS les comptes d'épargne. Il s’agit donc de statique .

Un équilibre doit être individuel . Par conséquent, il n'est pas statique.

 entrez la description de l'image ici

Un champ peut être affecté à la classe ou à une instance de classe. Par défaut, les champs sont des variables d'instance. En utilisant static , le champ devient une variable de classe. Il existe donc une et une seule horloge . Si vous apportez des modifications à un endroit, elles sont visibles partout. Les variables d'instance sont modifiées indépendamment les unes des autres.

Le mot clé static sert à désigner un champ ou une méthode comme appartenant à la classe elle-même et non à l'instance. Si vous utilisez votre code, si l'objet Clock est statique, toutes les instances de la classe Hello partageront ce membre de données Clock (champ) dans commun. Si vous le rendez non statique, chaque instance individuelle de Hello peut avoir un champ Clock unique.

Le problème est que vous avez ajouté une méthode main à votre classe Hello afin de pouvoir exécuter le code. Le problème ici est que la méthode main est statique et qu’elle ne peut donc pas faire référence à des champs ni à des méthodes non statiques. Vous pouvez résoudre ce problème de deux manières:

  1. Rendre tous les champs et méthodes de la classe Hello statiques afin qu'ils puissent être utilisés dans la méthode main . Ce n’est vraiment pas une bonne chose à faire (ou la mauvaise raison t rendre un champ et / ou une méthode statique)
  2. Créez une instance de votre classe Hello dans la méthode principale et accédez à tous ses champs et méthodes de la manière dont ils étaient destinés.

Pour vous, cela signifie la modification suivante de votre code:

package hello;

public class Hello {

    private Clock clock = new Clock();

    public Clock getClock() {
        return clock;
    }

    public static void main(String args[]) {
        Hello hello = new Hello();
        hello.getClock().sayTime();
    }
}

En Java, le mot clé static peut simplement être considéré comme indiquant les éléments suivants:

  

"Sans considération ni relation avec un cas particulier"

Si vous envisagez static de cette manière, il devient plus facile de comprendre son utilisation dans les divers contextes dans lesquels il est rencontré:

  • Un champ static est un champ qui appartient à la classe plutôt qu'à une instance particulière

  • Une méthode static est une méthode qui n'a aucune notion de this ; il est défini sur la classe et ne connaît aucune instance particulière de cette classe à moins qu'une référence ne lui soit transmise

  • Une classe membre static est une classe imbriquée sans aucune notion ni connaissance d'une instance de sa classe englobante (sauf si une référence à une instance de classe englobante lui est transmise)

Static fait du membre d'horloge un membre de classe au lieu d'un membre d'instance. Sans le mot-clé static, vous auriez besoin de créer une instance de la classe Hello (qui a une variable membre de l'horloge), par exemple.

Hello hello = new Hello();
hello.clock.sayTime();
Les méthodes

statiques n'utilisent aucune variable d'instance de la classe dans laquelle elles sont définies. Vous trouverez une très bonne explication de la différence sur cette page

J'ai développé un goût pour les méthodes statiques (uniquement si possible) dans "helper". classes.

La classe appelante n'a pas besoin de créer une autre variable membre (instance) de la classe d'assistance. Vous appelez juste les méthodes de la classe helper. La classe d'assistance est également améliorée car vous n'avez plus besoin d'un constructeur et vous n'avez besoin d'aucune variable membre (instance).

Il existe probablement d'autres avantages.

Peut également penser aux membres statiques ne disposant pas de "ceci". aiguille. Ils sont partagés entre toutes les instances.

Compréhension des concepts statiques

public class StaticPractise1 {
    public static void main(String[] args) {
        StaticPractise2 staticPractise2 = new StaticPractise2();
        staticPractise2.printUddhav(); //true
        StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */

        StaticPractise2.printUddhavsStatic1(); //true
        staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static  things and it organizes in its own heap. So, class static methods, object can't reference */

    }
}

Deuxième classe

public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}

main () est une méthode statique qui a deux restrictions fondamentales:

  1. La méthode statique ne peut pas utiliser un membre de données non statique ni appeler directement une méthode non statique.
  2. this () et super () ne peuvent pas être utilisés dans un contexte statique.

    class A {  
        int a = 40; //non static
        public static void main(String args[]) {  
            System.out.println(a);  
        }  
    }
    
  

Sortie: erreur de compilation

Les variables statiques ne sont accessibles que par les méthodes statiques. Ainsi, lorsque nous déclarons les variables statiques, ces méthodes getter et setter sont des méthodes statiques

les méthodes statiques sont un niveau de classe auquel nous pouvons accéder à l'aide du nom de la classe

Voici un exemple pour les variables statiques Getters And Setters:

public class Static 
{

    private static String owner;
    private static int rent;
    private String car;
    public String getCar() {
        return car;
    }
    public void setCar(String car) {
        this.car = car;
    }
    public static int getRent() {
        return rent;
    }
    public static void setRent(int rent) {
        Static.rent = rent;
    }
    public static String getOwner() {
        return owner;
    }

    public static void setOwner(String owner) {
        Static.owner = owner;
    }

}
  

Lorsque vous exécutez un projet, commencez par charger des objets statiques (variables, méthodes, blocs, etc.).

Lorsque vous exécutez ce projet, la méthode principale charge en premier. Parce que sa méthode statique . Ensuite, il recherche l'objet " a " objet .Mais l'objet n'est pas encore défini. Parce que ce n'est pas statique. Alors viens comme cette erreur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top