web-dev-qa-db-fra.com

Que fait le mot clé 'statique' dans une classe?

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 clock en ceci:

static Clock clock = new Clock();

Et ça a marché. 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 que l'on peut faire pour atteindre cet objet?

426
Click Upvote

Les membres static appartiennent à la classe au lieu d'une instance spécifique.

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

Etant donné que 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 se référer qu'aux membres static. Les membres d'instance peuvent bien sûr accéder aux membres static.

Note de côté: Bien entendu, les membres static peuvent accéder aux membres d'instance à travers 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]: En fonction des caractéristiques d'exécution, ce peut être un par ClassLoader ou AppDomain ou un thread, mais c'est à côté du point.

606
Mehrdad Afshari

Cela signifie qu'il n'y a qu'une seule instance de "clock" dans Hello, pas une pour chaque instance distincte de la classe "Hello", ou plus encore, cela signifie qu'il y aura une référence "d'horloge" communément partagée parmi toutes les instances de la classe "Bonjour".

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

À moins que vous n'ayez besoin de "clock" quelque part en dehors de main, cela fonctionnerait aussi bien:

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

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

Pour plus d'informations, voir le bit pertinent du Java Tutorial] 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 fait l'apparence comme si sleep est une méthode d'instance, mais c'est en fait une méthode statique - il toujours fait le thread actuel dort. Il est préférable de préciser cela dans le code de l'appelant:

// Clearer
Thread.sleep(5000);
96
Jon Skeet

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

Donc, si vous avez une variable: private static int i = 0; et que vous l'incrémentez (i++) dans un cas, la modification sera répercutée dans tous les cas. i sera désormais 1 dans tous les cas.

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

40
geowa4

Utilisation basique 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";
24
Vasil Valchev

Statique en 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

Des interfaces

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

Méthodes de la classe intérieure

Variables d'instance

Variables locales

Exemple:

Imaginons l'exemple suivant qui a 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();

    }
}

Sortie:

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();

    }
}

Sortie:

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 Final:

La variable globale déclarée comme finale et statique 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 en tant que final, aucun des objets ne peut changer de valeur car il est final. 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.

enter image description here

Ressource Image: Static Final

20
Virtual

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

À 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.

19
Elie

Cette discussion a jusqu'à présent ignoré les considérations relatives au chargeur de classe. À proprement parler, les champs Java statiques sont partagés par toutes les instances d'une classe pour un chargeur de classe.

13
Julien Chastang

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. Par conséquent, il est statique .

Un solde doit être individuel , il est donc pas statique.

enter image description here

13
Andrejs

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 n’ya donc qu’un et un seul clock. Si vous apportez des modifications à un endroit, elles sont visibles partout. Les variables d'instance sont modifiées indépendamment les unes des autres.

7
sblundy

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

"sans égard ni relation à aucun cas particulier"

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

  • 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)

6
scottb

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 en commun. Si vous le rendez non statique, chaque instance individuelle de Hello peut avoir un champ unique Clock.

Le problème est que vous avez ajouté une méthode main à votre classe Hello pour 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 ou méthodes non statiques. Vous pouvez résoudre ce problème de deux manières:

  1. Rendez tous les champs et méthodes de la classe Hello statiques afin qu'ils puissent être référencé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 à l'intérieur de la méthode principale et accédez à tous ses champs et méthodes comme prévu.

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();
    }
}
6
hfontanez

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

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. De même, la classe d'assistance est améliorée car vous n'avez plus besoin d'un constructeur et vous n'avez besoin d'aucune variable membre (instance).

Il y a probablement d'autres avantages.

5
javaguy

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

Hello hello = new Hello();
hello.clock.sayTime();
5
Stephen Doyle

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

5
Marc Novakowski

Peut aussi penser aux membres statiques n'ayant pas de pointeur "ceci". Ils sont partagés entre toutes les instances.

3
kal
//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
    }
}
3
Mohammad Parvez

Comprendre les 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 */

    }
}

Seconde classe

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

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
3
Uddhav Gautam

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

2
Bharthan

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.

méthodes statiques est un niveau de classe auquel nous pouvons accéder en utilisant le 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;
    }

}
1
Bala Krishna

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 son static method. Ensuite, il regarde l'objet "a" object .Mais l'objet n'est pas encore défini. Parce que ce n'est pas statique. Alors viens comme cette erreur.

0
Dev4World