web-dev-qa-db-fra.com

En termes simples, que signifie «statique» en Java?

On m'a dit plusieurs définitions, regardé sur Wikipedia, mais en tant que débutant de Java je ne suis toujours pas sûr de ce que cela signifie. Quiconque parle couramment Java = et idiot?

94
Philip Strong

statique signifie que la variable ou la méthode marquée comme telle est disponible au niveau de la classe. En d'autres termes, vous n'avez pas besoin de créer une instance de la classe pour y accéder.

public class Foo {
    public static void doStuff(){
        // does stuff
    }
}

Donc, au lieu de créer une instance de Foo puis d’appeler doStuff comme ceci:

Foo f = new Foo();
f.doStuff();

Vous appelez simplement la méthode directement contre la classe, comme suit:

Foo.doStuff();
237
inkedmn

En termes très simples, la classe est un moule et l’objet est la copie réalisée avec ce moule. Les statiques appartiennent au moule et sont accessibles directement sans effectuer de copies, d’où l’exemple ci-dessus.

37
Bostone

Le mot-clé static peut être utilisé de différentes manières dans Java et dans presque tous les cas, il s'agit d'un modificateur qui signifie que la chose qu'il modifie est utilisable sans instance d'objet englobant .

Java est un langage orienté objet et par défaut, la plupart du code que vous écrivez nécessite l'utilisation d'une instance de l'objet.

public class SomeObject {
    public int someField;
    public void someMethod() { };
    public Class SomeInnerClass { };
}

Pour utiliser someField, someMethod ou SomeInnerClass je dois d'abord créer une instance de SomeObject.

public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObject anInstance = new SomeObject();
        anInstance.someField = 7;
        anInstance.someMethod();
        //Non-static inner classes are usually not created outside of the
        //class instance so you don't normally see this syntax
        SomeInnerClass blah = anInstance.new SomeInnerClass();
    }
}

Si je déclare ces objets statiques, ils ne nécessitent pas d'instance englobante.

public class SomeObjectWithStaticStuff {
    public static int someField;
    public static void someMethod() { };
    public static Class SomeInnerClass { };
}

public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someMethod();
        SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass();
        //Or you can also do this if your imports are correct
        SomeInnerClass blah2 = new SomeInnerClass();
    }
}

Déclarer quelque chose de statique a plusieurs implications.

Tout d'abord, il ne peut y avoir qu'une seule valeur d'un champ statique dans toute votre application.

public class SomeOtherObject {
    public void doSomeStuff() {
        //Two objects, two different values
        SomeObject instanceOne = new SomeObject();
        SomeObject instanceTwo = new SomeObject();
        instanceOne.someField = 7;
        instanceTwo.someField = 10;
        //Static object, only ever one value
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someField = 10; //Redefines the above set
    }
}

Le deuxième problème est que les méthodes statiques et les classes internes ne peuvent pas accéder aux champs de l'objet englobant (puisqu'il n'y en a pas).

public class SomeObjectWithStaticStuff {
    private int nonStaticField;
    private void nonStaticMethod() { };

    public static void someStaticMethod() {
        nonStaticField = 7; //Not allowed
        this.nonStaticField = 7; //Not allowed, can never use *this* in static
        nonStaticMethod(); //Not allowed
        super.someSuperMethod(); //Not allowed, can never use *super* in static
    }

    public static class SomeStaticInnerClass {

        public void doStuff() {
            someStaticField = 7; //Not allowed
            nonStaticMethod(); //Not allowed
            someStaticMethod(); //This is ok
        }

    }
}

Le mot clé static peut également être appliqué aux interfaces internes, aux annotations et aux énumérations.

public class SomeObject {
    public static interface SomeInterface { };
    public static @interface SomeAnnotation { };
    public static enum SomeEnum { };
}

Dans tous ces cas, le mot clé est redondant et n'a aucun effet. Les interfaces, les annotations et les énumérations sont statiques par défaut car elles n'ont jamais de relation avec une classe interne.

Cela décrit simplement ce qu'ils font mot-clé. Il ne décrit pas si l'utilisation du mot clé est une mauvaise idée ou non. Cela peut être traité plus en détail dans d’autres questions telles que Est-ce qu’il est mauvais d’utiliser beaucoup de méthodes statiques?

Il existe également quelques utilisations moins courantes du mot clé static. Certaines importations statiques vous permettent d'utiliser des types statiques (y compris des interfaces, des annotations et des énumérations non marquées de manière redondante comme statiques) sans aucune qualification.

//SomeStaticThing.Java
public class SomeStaticThing {
    public static int StaticCounterOne = 0;
}

//SomeOtherStaticThing.Java
public class SomeOtherStaticThing {
    public static int StaticCounterTwo = 0;
}

//SomeOtherClass.Java
import static some.package.SomeStaticThing.*;
import some.package.SomeOtherStaticThing.*;

public class SomeOtherClass {
    public void doStuff() {
        StaticCounterOne++; //Ok
        StaticCounterTwo++; //Not ok
        SomeOtherStaticThing.StaticCounterTwo++; //Ok
    }
}

Enfin, il existe des initialiseurs statiques qui sont des blocs de code qui sont exécutés lors du premier chargement de la classe ( généralement juste avant l’instanciation d’une classe pour la première fois dans une application) et (comme méthodes statiques) ne peuvent pas accéder aux champs ni aux méthodes non statiques.

public class SomeObject {

    private static int x;

    static {
        x = 7;
    }
}
15
Pace

n autre excellent exemple d'attributs statiques et les opérations sont utilisées lorsque vous souhaitez appliquer le modèle de conception Singleton. En résumé, le modèle de conception Singleton garantit qu'un seul et unique objet d'une classe particulière est construit pendant la durée de vie de votre système. Pour garantir qu'un seul objet soit jamais construit, les implémentations typiques du modèle Singleton conservent une référence statique interne à l'instance d'objet autorisée unique, et l'accès à cette instance est contrôlé à l'aide d'une opération static.

7
mel3kings

En plus de ce que @inkedmn a souligné, un membre statique est au niveau de la classe. Par conséquent, ledit membre est chargé en mémoire par la machine virtuelle Java une fois pour cette classe (lorsque la classe est chargée). C'est-à-dire qu'il n'y a pas d'instances n d'un membre statique chargé pour l'instance n de la classe à laquelle il appartient.

3
wulfgarpro