Pouvez-vous nous dire pourquoi vous souhaitez définir des variables globales en Java?
Adam Paynter
44
Pour accéder à la variable depuis l'extérieur de la classe
aTJ
5
Vous devriez peut-être modifier votre question pour inclure un exemple de code illustrant précisément ce que vous voulez. Cela nous aiderait à recommander la meilleure solution.
Adam Paynter
7
@Adam: Je devrais pouvoir changer la valeur d'une variable dans une classe d'une autre classe.
aTJ
2
Non. Il n'y a pas de variables globales en Java.
Marquis de Lorne
Réponses:
261
Pour définir la variable globale, vous pouvez utiliser un mot-clé statique
Soyez prudent lorsque vous faites cela - lorsque la classe Global est déchargée, les variables seront null non définies. Si vous vendez votre application, cela se produira tôt ou tard et vous continuerez à chercher des erreurs partout mais pas là ....
user387184
10
Le staticmot-clé rend les variables accessibles globalement, tandis que leur classe est chargée.
sjas
22
À propos du déchargement de classe: s'il existe une chaîne de référence forte depuis n'importe quelle racine GC vers une instance de Global ou ses enfants, ou toute référence de compilation d'une classe chargée et non déchargeable vers Global, alors l'objet Class relatif à Global est fortement accessible, et donc le ClassLoader qui a chargé Global; ce qui rend impossible le déchargement de Global (puisque le déchargement de classe ne peut avoir lieu qu'après que le GC a complètement supprimé toute référence forte au ClassLoader qui a chargé une classe donnée). Si vous n'avez aucune référence, comment le déchargement pourrait-il être un problème ???
Bruno Reis
4
@Abi Je vous suggère de renommer votre classe Globalen quelque chose d'autre ( TestClass?) Afin de ne pas donner aux gens l'impression qu'il existe un Globalmot clé Java. Mieux vaut prévenir que guérir :)
Nicolas Rinaudo
53
Non. C'est par conception. Vous ne devriez pas le faire même si vous le pouviez.
Cela étant dit, vous pouvez créer un ensemble de membres statiques publics dans une classe nommée Globals.
Alors, quelle est la meilleure approche pour déclarer des constantes afin que toutes les méthodes de classe puissent y accéder?
Alston
6
Des messages de cette nature sont la raison pour laquelle les novices développent une phobie des variables globales, puis nous voyons toutes sortes de techniques flagrantes conçues pour contourner le tabou des variables globales, mais obtenir le même effet.
Evgeni Sergeev
38
Votez pour dire "ne le faites pas". sans expliquer ni se référer à une explication de pourquoi.
Jeff McCune
4
@JeffMcCune: pour rendre votre déclaration plus claire, "ne le faites pas" est en fait une connerie. Faites-le quand c'est utile. Par exemple, je dois déboguer mon code à l'aide de IAbstractLoggerBullshit et bien sûr System.err ne fonctionne pas dans cet environnement sur-conçu. Je ne peux pas jeter mon code en passant autour de la merde de l'enregistreur entre des centaines de classes d'adaptateur inutiles.
Jo So
6
Je vais le faire.
Sunfish flottant
40
Une autre façon est de créer une interface comme celle-ci:
publicinterfaceGlobalConstants{String name ="Chilly Billy";String address ="10 Chicken head Lane";}
Toute classe qui a besoin de les utiliser n'a qu'à implémenter l'interface:
Je me demande pourquoi cette réponse n'a (avant la mienne) aucun vote positif. N'apporte-t-il pas une réponse alternative raisonnable à celle fournie par toutes les autres réponses?
M_M
12
Java efficace par Joshua Bloch, Chapitre 4: Classes et interfaces, Article 19: Utiliser les interfaces uniquement pour définir les types "Le modèle d'interface constant est une mauvaise utilisation des interfaces." Ce livre mérite d'être lu! :)
MariuszS
1
De plus, à partir de JDK 1.5+, vous pouvez utiliser l'importation statique pour vos variables globales, l'implémentation n'est pas nécessaire.
MariuszS
9
.... D'accord, cela n'explique en fait rien, cela dit simplement qu'un livre a dit que c'était mauvais.
linkhyrule5
14
Voici un devis pour vous. Oracle dit: "Pour contourner ce problème, les gens mettent parfois des membres statiques dans une interface et héritent de cette interface. C'est une mauvaise idée. En fait, c'est une si mauvaise idée qu'il y a un nom pour cela: le Constant Interface Antipattern (voir Élément Java effectif 17). Le problème est que l'utilisation par une classe des membres statiques d'une autre classe n'est qu'un simple détail d'implémentation. Lorsqu'une classe implémente une interface, elle devient partie intégrante de l'API publique de la classe. Les détails d'implémentation ne doivent pas pénétrer dans API publiques. "
C'est vrai, bien que je pense que votre utilisation de "Globals" brouille un peu les choses :-). Quelque chose comme "Paramètres" serait plus approprié car ce n'est pas nécessairement Global.
Mark Peters
11
Beaucoup de bonnes réponses, mais je veux donner cet exemple car il est considéré comme le moyen le plus approprié d'accéder aux variables d'une classe par une autre classe: en utilisant des getters et des setters.
La raison pour laquelle vous utilisez les getters et setters de cette façon au lieu de simplement rendre la variable publique est la suivante. Disons que votre var va être un paramètre global que vous ne voulez JAMAIS que quelqu'un change pendant l'exécution de votre programme (dans le cas où vous développez du code avec une équipe), quelque chose comme peut-être l'URL d'un site Web. En théorie, cela peut changer et peut être utilisé plusieurs fois dans votre programme, vous devez donc utiliser une variable globale pour pouvoir tout mettre à jour en même temps. Mais vous ne voulez pas que quelqu'un d'autre vienne modifier cette variable (peut-être sans se rendre compte de son importance). Dans ce cas, vous n'incluez simplement pas de méthode setter et n'incluez que la méthode getter.
publicclassGlobal{privatestaticint var =5;publicstaticint getVar(){returnGlobal.var;}//If you do not want to change the var ever then do not include thispublicstaticvoid setVar(int var){Global.var = var;}}
Néanmoins, ce que nous avons est un staticmot-clé et c'est tout ce dont nous avons besoin. Rien n'existe en dehors de la classe en Java. Le staticmot-clé représente une variable de classe qui, contrairement à la variable d'instance, n'a qu'une seule copie et qui transcende toutes les instances de cette classe créée, ce qui signifie que sa valeur peut être modifiée et accessible dans toutes les instances à tout moment.
Si vous avez besoin d'une variable globale accessible au-delà des étendues, alors c'est la variable dont vous avez besoin, mais sa portée n'existe que là où se trouve la classe, et ce sera tout.
À vrai dire, il n'y a pas de concept de "GLOBAL" dans un programme Java OO
Néanmoins, il y a une certaine vérité derrière votre question, car il y aura des cas où vous voudrez exécuter une méthode à n'importe quelle partie du programme. Par exemple --- méthode random () dans l'application Phrase-O-Matic; c'est une méthode qui devrait être appelable de n'importe où dans un programme.
Donc, pour satisfaire les choses comme ci-dessus "Nous devons avoir des variables et des méthodes de type global"
DÉCLARER UNE VARIABLE GLOBALE.
1.Mark the variable as publicstaticfinalWhile declaring.
DÉCLARER UNE MÉTHODE COMME GLOBALE .
1.Mark the method as publicstaticWhile declaring.
Parce que j'ai déclaré les variables globales et la méthode comme statiques, vous pouvez les appeler où vous le souhaitez en utilisant simplement le code suivant
ClassName.X
REMARQUE : X peut être un nom de méthode ou un nom de variable selon l'exigence et ClassName est le nom de la classe dans laquelle vous les avez déclarés.
Assurez-vous que lorsque vous déplacez votre code hors du sol de la salle de découpe et dans la version, vous supprimez ou commentez cette fonctionnalité.
Si vous avez une méthode de travail, comme un randomiseur, je vous suggère de créer un package "Toolbox"! Tous les codeurs devraient en avoir un, puis chaque fois que vous souhaitez l'utiliser dans un .java, importez-le simplement!
Il n'existe pas de variable véritablement globale en Java. Chaque variable statique doit appartenir à une classe (comme System.out), mais lorsque vous avez décidé dans quelle classe elle ira, vous pouvez vous y référer de partout chargée par le même chargeur de classe.
Notez que les variables statiques doivent toujours être protégées lors de la mise à jour pour éviter les conditions de concurrence.
Comme vous le devinez probablement dans la réponse, il n'y a pas de variables globales en Java et la seule chose que vous pouvez faire est de créer une classe avec des membres statiques:
publicclassGlobal{publicstaticint a;}
Vous pouvez l'utiliser avec Global.aailleurs. Cependant, si vous utilisez Java 1.5 ou mieux, vous pouvez utiliser la import staticmagie pour la faire apparaître encore plus comme une vraie variable globale:
importstatic test.Global.*;publicclassUseGlobal{publicvoid foo(){int i = a;}}
Et voilà !
Maintenant, c'est loin d'être une bonne pratique, comme vous pouvez le voir dans les publicités: ne faites pas cela à la maison
Il n'y a pas de variables globales en Java, mais il existe des classes globales avec des champs publics. Vous pouvez utiliser la fonction d'importation statique de java 5 pour la faire ressembler presque à des variables globales.
Une variable globale doit-elle être définitive? Pourquoi?
Konerak
1
"final" signifie "constant", c'est donc une constante globale.
duffymo
1
non, c'est ce que signifie la variable globale si vous souhaitez partager cette variable et modifier également les données, puis supprimez-les, finalmais cela dépend certainement de la façon dont vous souhaitez partager, où vous utilisez et tout,
Jigar Joshi
Quel est le type de CODEdans cet exemple? Où est-il défini?
M_M
Notez également: CODE est dans toutes les majuscules, comme sa notation java commune pour utiliser toutes les majuscules pour les variables que vous déclarez définitives, et n'ont pas l'intention de changer au cours d'un programme.
Dan Ciborowski - MSFT
1
Création d'un fichier indépendant, par exemple. Example.java pour utiliser la 1ère solution, c'est très bien. Vous pouvez le faire également dans l'application, par exemple si les variables globales sont spéciales pour votre application actuelle, etc.:
Créez une classe au début et déclarez vos variables dedans:
Au lieu de voter vers le bas, pouvez-vous me dire ce qui ne va pas avec cette solution? Je l'utilise sur une base constante et c'est la plus pratique. Je ne peux donc pas faire autrement que de considérer ce downvote comme une chose personnelle ou simplement par une personne stupide.
Apostolos
1
Si vous devez mettre à jour la propriété globale, une simple classe wrapper getter / setter peut être utilisée comme variable globale. Un exemple typique est illustré ci-dessous.
Selon le concept, les variables globales, également connues sous le nom de variable d'instance, sont les variables au niveau de la classe, c'est-à-dire qu'elles sont définies à l'intérieur d'une classe mais à l'extérieur des méthodes. Afin de les rendre complètement disponibles et de les utiliser, fournissez directement le mot-clé statique. Donc, si j'écris un programme pour une opération arithmétique simple et qu'il nécessite une paire de nombres, deux variables d'instance sont définies comme telles:
De plus, l'utilisation de mots clés statiques avant les variables d'instance nous permet de ne pas spécifier encore et encore les types de données pour les mêmes variables. Écrivez simplement la variable directement.
Il n'y a pas de variables globales en Java; elles ne sont pas également appelées variables d'instance; les définir comme static«ne les rend pas entièrement disponibles». Le premier paragraphe est un non-sens. L'exemple est une mauvaise pratique.
Marquis de Lorne
0
En général, Java n'a pas de variables globales. À l'exception des variables locales, toutes les variables relèvent de la portée de n'importe quelle classe définie dans le programme. Nous pouvons avoir des variables statiques pour avoir la portée des variables globales.
La programmation orientée objet est construite avec la compréhension que la portée des variables est étroitement exclusive à l'objet de classe qui encapsule ces variables.
Le problème avec la création de "variables globales" est que ce n'est pas la norme de l'industrie pour Java. Ce n'est pas la norme de l'industrie car il permet à plusieurs classes de manipuler des données asynchronisées, si vous exécutez une application multi-thread, cela devient un peu plus compliqué et dangereux en termes de sécurité des threads. Il existe plusieurs autres raisons pour lesquelles l'utilisation de variables globales est inefficace, mais si vous voulez éviter cela, je vous suggère de recourir à la programmation orientée aspect .
La programmation orientée aspect résout ce problème en mettant la classe parent en charge de la portée via quelque chose appelé "conseils", ce qui ajoute un comportement supplémentaire au code sans le modifier réellement. Il propose des solutions aux préoccupations transversales ou à l'utilisation globale des variables.
Spring est un cadre Java qui utilise AOP, et bien qu'il soit traditionnellement utilisé pour les applications Web, l'application principale peut être utilisée universellement dans tout le cadre Java (8.0 inclus). Cela pourrait être une direction que vous souhaitez explorer davantage.
Je considère la qualification de variable globale comme une variable qui peut être consultée et modifiée n'importe où dans le code sans se soucier de l'appel statique / d'instance ni passer de référence d'une classe à une autre.
vous devrez avoir une référence d'une instance de la classe A et mettre à jour la valeur dans la classe B comme ceci:
int initialValue =2;int newValue =3;
A a =new A(initialValue);
B b =new B();
b.passA(a);
b.changeMyVar(newValue);
assertEquals(a.getMyVar(),newValue);// true
Solution
Donc, ma solution à cela (même si je ne suis pas sûr que ce soit une bonne pratique) est d'utiliser un singleton:
Vous pouvez désormais obtenir l'instance unique globale n'importe où avec:
Globals globals =Globals.getInstance();// and read and write to myVar with the getter and setter like int myVar = globals.getMyVar();
global.setMyVar(3);
// Get the access of global while retaining priveleges.// You can access variables in one class from another, with provisions.// The primitive must be protected or no modifier (seen in example).// the first classpublicclass farm{int eggs;// an integer to be set by constructor
fox afox;// declaration of a fox object// the constructor inits
farm(){
eggs =4;
afox =new fox();// an instance of a fox object// show count of eggs before the fox arrivesSystem.out.println("Count of eggs before: "+ eggs);// call class fox, afox method, pass myFarm as a reference
afox.stealEgg(this);// show the farm class, myFarm, primitive valueSystem.out.println("Count of eggs after : "+ eggs);}// end constructorpublicstaticvoid main(String[] args){// instance of a farm class object
farm myFarm =new farm();};// end main}// end class// the second classpublicclass fox{// theFarm is the myFarm object instance// any public, protected, or "no modifier" variable is accessiblevoid stealEgg(farm theFarm){--theFarm.eggs;}}// end class
vous pouvez maintenant accéder à a et b de n'importe où en appelant
Tools.a;Tools.b;
Vous avez raison ... spécialement dans J2ME ... Vous pouvez éviter NullPointerException en mettant à l'intérieur de votre constructeur MidLet (initialisation proggy) cette ligne de code:
newTools();
Cela garantit que les outils seront alloués avant toute instruction qui l'utilise.
Réponses:
Pour définir la variable globale, vous pouvez utiliser un mot-clé statique
vous pouvez maintenant accéder à a et b de n'importe où en appelant
la source
static
mot-clé rend les variables accessibles globalement, tandis que leur classe est chargée.Global
en quelque chose d'autre (TestClass
?) Afin de ne pas donner aux gens l'impression qu'il existe unGlobal
mot clé Java. Mieux vaut prévenir que guérir :)Non. C'est par conception. Vous ne devriez pas le faire même si vous le pouviez.
Cela étant dit, vous pouvez créer un ensemble de membres statiques publics dans une classe nommée Globals.
mais vous ne devriez vraiment pas :). Sérieusement .. ne le faites pas.
la source
Une autre façon est de créer une interface comme celle-ci:
Toute classe qui a besoin de les utiliser n'a qu'à implémenter l'interface:
la source
Il vaut mieux utiliser l'injection de dépendance:
la source
Beaucoup de bonnes réponses, mais je veux donner cet exemple car il est considéré comme le moyen le plus approprié d'accéder aux variables d'une classe par une autre classe: en utilisant des getters et des setters.
La raison pour laquelle vous utilisez les getters et setters de cette façon au lieu de simplement rendre la variable publique est la suivante. Disons que votre var va être un paramètre global que vous ne voulez JAMAIS que quelqu'un change pendant l'exécution de votre programme (dans le cas où vous développez du code avec une équipe), quelque chose comme peut-être l'URL d'un site Web. En théorie, cela peut changer et peut être utilisé plusieurs fois dans votre programme, vous devez donc utiliser une variable globale pour pouvoir tout mettre à jour en même temps. Mais vous ne voulez pas que quelqu'un d'autre vienne modifier cette variable (peut-être sans se rendre compte de son importance). Dans ce cas, vous n'incluez simplement pas de méthode setter et n'incluez que la méthode getter.
la source
Il n'y a pas de variable globale en Java
Néanmoins, ce que nous avons est un
static
mot-clé et c'est tout ce dont nous avons besoin. Rien n'existe en dehors de la classe en Java. Lestatic
mot-clé représente une variable de classe qui, contrairement à la variable d'instance, n'a qu'une seule copie et qui transcende toutes les instances de cette classe créée, ce qui signifie que sa valeur peut être modifiée et accessible dans toutes les instances à tout moment.Si vous avez besoin d'une variable globale accessible au-delà des étendues, alors c'est la variable dont vous avez besoin, mais sa portée n'existe que là où se trouve la classe, et ce sera tout.
la source
À vrai dire, il n'y a pas de concept de "GLOBAL" dans un programme Java OO
Néanmoins, il y a une certaine vérité derrière votre question, car il y aura des cas où vous voudrez exécuter une méthode à n'importe quelle partie du programme. Par exemple --- méthode random () dans l'application Phrase-O-Matic; c'est une méthode qui devrait être appelable de n'importe où dans un programme.
Donc, pour satisfaire les choses comme ci-dessus "Nous devons avoir des variables et des méthodes de type global"
DÉCLARER UNE VARIABLE GLOBALE.
DÉCLARER UNE MÉTHODE COMME GLOBALE .
Parce que j'ai déclaré les variables globales et la méthode comme statiques, vous pouvez les appeler où vous le souhaitez en utilisant simplement le code suivant
ClassName.X
REMARQUE : X peut être un nom de méthode ou un nom de variable selon l'exigence et ClassName est le nom de la classe dans laquelle vous les avez déclarés.
la source
Rien ne devrait être global, à l'exception des constantes.
Mettez cela dans votre classe principale. Dans d'autres fichiers .java, utilisez-le via:
Assurez-vous que lorsque vous déplacez votre code hors du sol de la salle de découpe et dans la version, vous supprimez ou commentez cette fonctionnalité.
Si vous avez une méthode de travail, comme un randomiseur, je vous suggère de créer un package "Toolbox"! Tous les codeurs devraient en avoir un, puis chaque fois que vous souhaitez l'utiliser dans un .java, importez-le simplement!
la source
Il n'existe pas de variable véritablement globale en Java. Chaque variable statique doit appartenir à une classe (comme System.out), mais lorsque vous avez décidé dans quelle classe elle ira, vous pouvez vous y référer de partout chargée par le même chargeur de classe.
Notez que les variables statiques doivent toujours être protégées lors de la mise à jour pour éviter les conditions de concurrence.
la source
De cette façon, vous pouvez y accéder avec
GlobalClass.x
etGlobalClass.s
la source
vous pouvez appeler où vous voulez:
la source
Comme vous le devinez probablement dans la réponse, il n'y a pas de variables globales en Java et la seule chose que vous pouvez faire est de créer une classe avec des membres statiques:
Vous pouvez l'utiliser avec
Global.a
ailleurs. Cependant, si vous utilisez Java 1.5 ou mieux, vous pouvez utiliser laimport static
magie pour la faire apparaître encore plus comme une vraie variable globale:Et voilà !
Maintenant, c'est loin d'être une bonne pratique, comme vous pouvez le voir dans les publicités: ne faites pas cela à la maison
la source
Il n'y a pas de variables globales en Java, mais il existe des classes globales avec des champs publics. Vous pouvez utiliser la fonction d'importation statique de java 5 pour la faire ressembler presque à des variables globales.
la source
Généralement la variable globale (je suppose que vous la comparez avec C, Cpp) définit comme
public static final
comme
Les ENUM sont également utiles dans un tel scénario:
Par exemple
Calendar.JANUARY
)la source
final
mais cela dépend certainement de la façon dont vous souhaitez partager, où vous utilisez et tout,CODE
dans cet exemple? Où est-il défini?Création d'un fichier indépendant, par exemple. Example.java pour utiliser la 1ère solution, c'est très bien. Vous pouvez le faire également dans l'application, par exemple si les variables globales sont spéciales pour votre application actuelle, etc.:
Créez une classe au début et déclarez vos variables dedans:
Vous pouvez ensuite accéder à ces variables - en les utilisant comme «Globals.month_number», etc. - à partir de partout dans votre application.
la source
Si vous devez mettre à jour la propriété globale, une simple classe wrapper getter / setter peut être utilisée comme variable globale. Un exemple typique est illustré ci-dessous.
la source
Selon le concept, les variables globales, également connues sous le nom de variable d'instance, sont les variables au niveau de la classe, c'est-à-dire qu'elles sont définies à l'intérieur d'une classe mais à l'extérieur des méthodes. Afin de les rendre complètement disponibles et de les utiliser, fournissez directement le mot-clé statique. Donc, si j'écris un programme pour une opération arithmétique simple et qu'il nécessite une paire de nombres, deux variables d'instance sont définies comme telles:
De plus, l'utilisation de mots clés statiques avant les variables d'instance nous permet de ne pas spécifier encore et encore les types de données pour les mêmes variables. Écrivez simplement la variable directement.
la source
static
«ne les rend pas entièrement disponibles». Le premier paragraphe est un non-sens. L'exemple est une mauvaise pratique.En général, Java n'a pas de variables globales. À l'exception des variables locales, toutes les variables relèvent de la portée de n'importe quelle classe définie dans le programme. Nous pouvons avoir des variables statiques pour avoir la portée des variables globales.
la source
sans
static
cela, c'est possible aussi:la source
La programmation orientée objet est construite avec la compréhension que la portée des variables est étroitement exclusive à l'objet de classe qui encapsule ces variables.
Le problème avec la création de "variables globales" est que ce n'est pas la norme de l'industrie pour Java. Ce n'est pas la norme de l'industrie car il permet à plusieurs classes de manipuler des données asynchronisées, si vous exécutez une application multi-thread, cela devient un peu plus compliqué et dangereux en termes de sécurité des threads. Il existe plusieurs autres raisons pour lesquelles l'utilisation de variables globales est inefficace, mais si vous voulez éviter cela, je vous suggère de recourir à la programmation orientée aspect .
La programmation orientée aspect résout ce problème en mettant la classe parent en charge de la portée via quelque chose appelé "conseils", ce qui ajoute un comportement supplémentaire au code sans le modifier réellement. Il propose des solutions aux préoccupations transversales ou à l'utilisation globale des variables.
Spring est un cadre Java qui utilise AOP, et bien qu'il soit traditionnellement utilisé pour les applications Web, l'application principale peut être utilisée universellement dans tout le cadre Java (8.0 inclus). Cela pourrait être une direction que vous souhaitez explorer davantage.
la source
Comprendre le problème
Je considère la qualification de variable globale comme une variable qui peut être consultée et modifiée n'importe où dans le code sans se soucier de l'appel statique / d'instance ni passer de référence d'une classe à une autre.
Habituellement, si vous avez la classe A
et souhaitez accéder et mettre
myvar
à jour dans une classe B,vous devrez avoir une référence d'une instance de la classe A et mettre à jour la valeur dans la classe B comme ceci:
Solution
Donc, ma solution à cela (même si je ne suis pas sûr que ce soit une bonne pratique) est d'utiliser un singleton:
Vous pouvez désormais obtenir l'instance unique globale n'importe où avec:
la source
la source
Pour définir la variable globale, vous pouvez utiliser un mot-clé statique
vous pouvez maintenant accéder à a et b de n'importe où en appelant
Vous avez raison ... spécialement dans J2ME ... Vous pouvez éviter NullPointerException en mettant à l'intérieur de votre constructeur MidLet (initialisation proggy) cette ligne de code:
Cela garantit que les outils seront alloués avant toute instruction qui l'utilise.
C'est tout!
la source