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?
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.
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();
}
}
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);
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.
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";
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.
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
À 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 classe. À proprement parler, les champs Java statiques sont partagés par toutes les instances d'une classe pour un chargeur de classe.
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.
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)
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:
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)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();
}
}
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.
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();
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
Peut aussi penser aux membres statiques n'ayant pas de pointeur "ceci". Ils sont partagés entre toutes les instances.
//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
}
}
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");
}
}
main()
est une méthode statique qui a deux restrictions fondamentales:
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
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;
}
}
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.