¿Puede decirnos por qué quiere definir variables globales en Java?
Adam Paynter
44
Para acceder a la variable desde fuera de la clase
aTJ
55
Tal vez debería editar su pregunta para incluir un código de muestra que ilustre exactamente lo que desea. Nos ayudaría a recomendar la mejor solución.
Adam Paynter
77
@ Adam: debería poder cambiar el valor de una variable en una clase de otra clase.
aTJ
2
Usted no No hay variables globales en Java.
Marqués de Lorne
Respuestas:
261
Para definir la variable global, puede utilizar palabras clave estáticas
Tenga cuidado al hacer esto: cuando la clase Global se descargue, las variables serán nulas indefinidas. Si vende su aplicación, esto sucederá tarde o temprano y sigue buscando errores en todas partes, pero no allí ...
user387184
10
La staticpalabra clave hace que las variables sean accesibles globalmente, mientras se carga su clase.
sjas
22
Acerca de la descarga de clases: si hay una cadena de referencia fuerte desde cualquier raíz de GC a una instancia de Global o sus hijos, o cualquier referencia en tiempo de compilación de una clase cargada y no descargable a Global, entonces el objeto de clase relativo a Global es fuertemente accesible y, por lo tanto, también lo es el ClassLoader que cargó Global; lo que hace que sea imposible descargar Global (ya que la descarga de clases solo puede ocurrir después de que el GC elimine por completo cualquier referencia fuerte al ClassLoader que cargó una clase dada). Si no tiene referencias, ¿cómo podría ser un problema la descarga?
Bruno Reis
44
@Abi, le sugiero que cambie el nombre de su clase Globala otra cosa ( TestClass?) Para no dar a la gente la impresión de que existe una Globalpalabra clave Java. Mejor prevenir que curar :)
Nicolas Rinaudo
53
Usted no Eso es por diseño. No deberías hacerlo incluso si pudieras.
Dicho esto, podría crear un conjunto de miembros públicos estáticos en una clase llamada Globals.
Entonces, ¿cuál es el mejor enfoque que puedo declarar constantes para que todos los métodos de clase puedan acceder a ellos?
Alston
66
Las publicaciones de esta naturaleza son la razón por la cual los novatos desarrollan una fobia global variable, y luego vemos todo tipo de técnicas atroces que se diseñan para sortear el tabú de la variable global, pero logran el mismo efecto.
Evgeni Sergeev
38
Voto negativo para decir "no lo hagas". sin explicar o referirse a una explicación de por qué.
Jeff McCune
44
@JeffMcCune: para aclarar tu declaración, "no lo hagas" es realmente una mentira. Hazlo cuando sea útil. Por ejemplo, tengo que depurar mi código usando algunos IAbstractLoggerBullshit y, por supuesto, System.err no funciona en este entorno de ingeniería excesiva. No puedo ensuciar mi código pasando la basura del registrador entre cientos de clases de adaptadores inútiles.
Jo So
66
Voy a hacerlo.
Flotante Sunfish
40
Otra forma es crear una interfaz como esta:
publicinterfaceGlobalConstants{String name ="Chilly Billy";String address ="10 Chicken head Lane";}
Cualquier clase que necesite usarlos solo tiene que implementar la interfaz:
Me pregunto por qué esta respuesta (antes de la mía) no tiene votos positivos. ¿No proporciona una respuesta alternativa razonable a la proporcionada por todas las otras respuestas?
M_M
12
Java efectivo por Joshua Bloch, Capítulo 4: Clases e interfaces, Elemento 19: Usar interfaces solo para definir tipos "El patrón de interfaz constante es un mal uso de las interfaces". ¡Vale la pena leer este libro! :)
MariuszS
1
Además, desde JDK 1.5+ puede usar la importación estática para sus variables globales, no es necesaria la implementación.
MariuszS
99
.... Correcto, eso en realidad no explica nada, solo dice que algún libro dijo que era malo.
linkhyrule5
14
Aquí hay una cita para ti. Oracle dice: "Para evitar esto, las personas a veces ponen miembros estáticos en una interfaz y heredan de esa interfaz. Esta es una mala idea. De hecho, es una idea tan mala que hay un nombre para ello: el Antipatrón de Interfaz Constante (ver Artículo 17 de Java efectivo.) El problema es que el uso de una clase de los miembros estáticos de otra clase es un mero detalle de implementación. Cuando una clase implementa una interfaz, se convierte en parte de la API pública de la clase. Los detalles de implementación no deben filtrarse API públicas ".
Es cierto, aunque creo que su uso de "Globals" confunde un poco las cosas :-). Algo así como "Parámetros" sería más apropiado ya que no es necesariamente Global.
Mark Peters el
11
Muchas buenas respuestas, pero quiero dar este ejemplo, ya que se considera la forma más adecuada de acceder a las variables de una clase por otra clase: usando getters y setters.
La razón por la que usa getters y setters de esta manera en lugar de simplemente hacer pública la variable es la siguiente. Digamos que su var será un parámetro global que NUNCA desea que alguien cambie durante la ejecución de su programa (en el caso de que esté desarrollando código con un equipo), algo así como la URL de un sitio web. En teoría, esto podría cambiar y puede usarse muchas veces en su programa, por lo que desea usar una variable global para poder actualizar todo de una vez. Pero no desea que alguien más entre y cambie esta var (posiblemente sin darse cuenta de lo importante que es). En ese caso, simplemente no incluye un método setter, y solo incluye el método 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;}}
Sin embargo, lo que tenemos es una staticpalabra clave y eso es todo lo que necesitamos. Nada existe fuera de clase en Java. La staticpalabra clave representa una variable de clase que, a diferencia de la variable de instancia, solo tiene una copia y trasciende todas las instancias de esa clase creada, lo que significa que su valor se puede cambiar y acceder a todas las instancias en cualquier momento.
Si necesita una variable global a la que se pueda acceder más allá de los ámbitos, entonces esta es la variable que necesita, pero su alcance existe solo donde está la clase, y eso será todo.
En verdad, no hay un concepto de "GLOBAL" en un programa Java OO
Sin embargo, hay algo de verdad detrás de su pregunta porque habrá algunos casos en los que desee ejecutar un método en cualquier parte del programa. Por ejemplo --- método random () en la aplicación Phrase-O-Matic; es un método que se puede llamar desde cualquier parte de un programa.
Entonces, para satisfacer las cosas como arriba "Necesitamos tener variables y métodos similares a los globales"
PARA DECLARAR UNA VARIABLE COMO GLOBAL.
1.Mark the variable as publicstaticfinalWhile declaring.
PARA DECLARAR UN MÉTODO COMO GLOBAL .
1.Mark the method as publicstaticWhile declaring.
Debido a que declaró que las variables globales y el método son estáticos, puede llamarlos a cualquier lugar que desee simplemente con la ayuda del siguiente código
ClassName.X
NOTA : X puede ser el nombre del método o el nombre de la variable según el requisito y ClassName es el nombre de la clase en la que los declaró.
Asegúrese de que cuando mueva su código del piso de la sala de corte y lo libere, quite o comente esta funcionalidad.
Si tiene un método de caballo de batalla, como un aleatorizador, le sugiero que cree un paquete "Toolbox". Todos los codificadores deben tener uno, luego, cuando quiera usarlo en un .java, ¡simplemente impórtelo!
No existe una variable verdaderamente global en Java. Cada variable estática debe pertenecer a alguna clase (como System.out), pero cuando haya decidido en qué clase entrará, puede consultarla desde cualquier lugar cargado por el mismo cargador de clases.
Tenga en cuenta que las variables estáticas siempre deben protegerse al actualizar para evitar condiciones de carrera.
Java no proporciona una variable global funcionalmente, pero si desea tener un concepto de variable global, podemos hacer uso de la palabra clave estática
Abi
3
publicclassGlobalClass{publicstaticint x =37;publicstaticString s ="aaa";}
De esta manera puede acceder a ellos con GlobalClass.xyGlobalClass.s
Como probablemente adivine por la respuesta, no hay variables globales en Java y lo único que puede hacer es crear una clase con miembros estáticos:
publicclassGlobal{publicstaticint a;}
Puedes usarlo en Global.aotro lugar. Sin embargo, si usa Java 1.5 o superior, puede usar la import staticmagia para que se vea aún más como una variable global real:
importstatic test.Global.*;publicclassUseGlobal{publicvoid foo(){int i = a;}}
Y voilà !
Ahora, esto está lejos de ser una mejor práctica, como puede ver en los comerciales: no haga esto en casa
No hay variables globales en Java, pero hay clases globales con campos públicos. Puede usar la función de importación estática de java 5 para que se vea casi como variables globales.
¿Una variable global necesita ser final? ¿Por qué?
Konerak
1
"final" significa "constante", por lo que esta es una constante global.
duffymo
1
no, eso es lo que significa la variable Global si quieres compartir esa variable y cambiar los datos y luego simplemente eliminar, finalpero ciertamente depende de cómo quieras compartir, dónde estás usando y todo,
Jigar Joshi
¿Cuál es el tipo de CODEen este ejemplo? ¿Dónde se define?
M_M
También tenga en cuenta: CODE está en mayúsculas, como su notación común de Java para usar todas las mayúsculas para las variables que declara como finales, y no tiene la intención de cambiar durante el curso de un programa.
Dan Ciborowski - MSFT
1
Crear un archivo independiente, por ejemplo. Example.java para usar la primera solución, está bien. Puede hacerlo también dentro de la aplicación, por ejemplo, si las variables globales son especiales para su aplicación actual, etc.
Crea una clase al principio y declara tus variables allí:
En lugar de votar a favor, ¿puede decirme qué hay de malo en esta solución? Lo estoy usando de manera constante y es el más conveniente. Así que no puedo hacer otra cosa que considerar este voto negativo como algo personal o simplemente hecho por una persona estúpida.
Apostolos
1
Si necesita actualizar la propiedad global, se puede usar una clase de contenedor getter / setter simple como variable global. Un ejemplo típico se muestra a continuación.
Siguiendo el concepto, las variables globales, también conocidas como variables de instancia, son las variables de nivel de clase, es decir, se definen dentro de una clase pero fuera de los métodos. Para que estén disponibles por completo y usarlos directamente, proporcione la palabra clave estática. Entonces, si estoy escribiendo un programa para una operación aritmética simple y requiere un par de números, entonces dos variables de instancia se definen como tales:
Además, el uso de palabras clave estáticas antes de las variables de instancia nos permite no especificar tipos de datos para las mismas variables una y otra vez. Simplemente escriba la variable directamente.
No hay variables globales en Java; no se conocen también como variables de instancia; definirlos como static"no los hace disponibles por completo". El primer párrafo no tiene sentido. El ejemplo es una mala práctica.
Marqués de Lorne
0
En general, Java no tiene ninguna variable global. Aparte de las variables locales, todas las variables entran dentro del alcance de cualquier clase definida en el programa. Podemos tener variables estáticas para tener el alcance de las variables globales.
La programación orientada a objetos se construye con el entendimiento de que el alcance de las variables es muy exclusivo del objeto de clase que encapsula esas variables.
El problema con la creación de "variables globales" es que no es estándar de la industria para Java. No es un estándar de la industria porque permite que múltiples clases manipulen datos asincronizados, si está ejecutando una aplicación multiproceso, esto se vuelve un poco más complicado y peligroso en términos de seguridad de subprocesos. Hay varias otras razones por las cuales el uso de variables globales no es efectivo, pero si desea evitar eso, le sugiero que recurra a la Programación Orientada a Aspectos .
La Programación Orientada a Aspectos niega este problema al poner a la clase padre a cargo del alcance a través de algo llamado "consejos", que agrega un comportamiento adicional al código sin modificarlo realmente. Ofrece soluciones a problemas transversales o uso de variables globales.
Spring es un marco de Java que utiliza AOP, y aunque se usa tradicionalmente para aplicaciones web, la aplicación central se puede usar universalmente en todo el marco de Java (8.0 incluido). Esta podría ser una dirección que desea explorar más.
Considero la calificación de la variable global como una variable a la que se puede acceder y cambiar en cualquier parte del código sin preocuparse por la llamada estática / instancia o pasar cualquier referencia de una clase a otra.
necesitará tener una referencia de una instancia de la clase A y actualizar el valor en la clase B de esta manera:
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
Solución
Entonces, mi solución a esto, (incluso si no estoy seguro de si es una buena práctica), es usar un singleton:
Ahora puede obtener la instancia única global en cualquier lugar con:
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
ahora puede acceder a ayb desde cualquier lugar llamando
Tools.a;Tools.b;
Tienes razón ... especialmente en J2ME ... Puedes evitar NullPointerException poniendo dentro de tu constructor MidLet (inicialización de proggy) esta línea de código:
newTools();
Esto asegura que las Herramientas se asignarán antes de cualquier instrucción que lo use.
Respuestas:
Para definir la variable global, puede utilizar palabras clave estáticas
ahora puede acceder a ayb desde cualquier lugar llamando
fuente
static
palabra clave hace que las variables sean accesibles globalmente, mientras se carga su clase.Global
a otra cosa (TestClass
?) Para no dar a la gente la impresión de que existe unaGlobal
palabra clave Java. Mejor prevenir que curar :)Usted no Eso es por diseño. No deberías hacerlo incluso si pudieras.
Dicho esto, podría crear un conjunto de miembros públicos estáticos en una clase llamada Globals.
pero realmente no deberías :) En serio ... no lo hagas.
fuente
Otra forma es crear una interfaz como esta:
Cualquier clase que necesite usarlos solo tiene que implementar la interfaz:
fuente
Es mejor usar la inyección de dependencia:
fuente
Muchas buenas respuestas, pero quiero dar este ejemplo, ya que se considera la forma más adecuada de acceder a las variables de una clase por otra clase: usando getters y setters.
La razón por la que usa getters y setters de esta manera en lugar de simplemente hacer pública la variable es la siguiente. Digamos que su var será un parámetro global que NUNCA desea que alguien cambie durante la ejecución de su programa (en el caso de que esté desarrollando código con un equipo), algo así como la URL de un sitio web. En teoría, esto podría cambiar y puede usarse muchas veces en su programa, por lo que desea usar una variable global para poder actualizar todo de una vez. Pero no desea que alguien más entre y cambie esta var (posiblemente sin darse cuenta de lo importante que es). En ese caso, simplemente no incluye un método setter, y solo incluye el método getter.
fuente
No hay una variable global en Java
Sin embargo, lo que tenemos es una
static
palabra clave y eso es todo lo que necesitamos. Nada existe fuera de clase en Java. Lastatic
palabra clave representa una variable de clase que, a diferencia de la variable de instancia, solo tiene una copia y trasciende todas las instancias de esa clase creada, lo que significa que su valor se puede cambiar y acceder a todas las instancias en cualquier momento.Si necesita una variable global a la que se pueda acceder más allá de los ámbitos, entonces esta es la variable que necesita, pero su alcance existe solo donde está la clase, y eso será todo.
fuente
En verdad, no hay un concepto de "GLOBAL" en un programa Java OO
Sin embargo, hay algo de verdad detrás de su pregunta porque habrá algunos casos en los que desee ejecutar un método en cualquier parte del programa. Por ejemplo --- método random () en la aplicación Phrase-O-Matic; es un método que se puede llamar desde cualquier parte de un programa.
Entonces, para satisfacer las cosas como arriba "Necesitamos tener variables y métodos similares a los globales"
PARA DECLARAR UNA VARIABLE COMO GLOBAL.
PARA DECLARAR UN MÉTODO COMO GLOBAL .
Debido a que declaró que las variables globales y el método son estáticos, puede llamarlos a cualquier lugar que desee simplemente con la ayuda del siguiente código
ClassName.X
NOTA : X puede ser el nombre del método o el nombre de la variable según el requisito y ClassName es el nombre de la clase en la que los declaró.
fuente
Nada debe ser global, excepto las constantes.
Pon esto dentro de tu clase principal. En otros archivos .java, úsalo a través de:
Asegúrese de que cuando mueva su código del piso de la sala de corte y lo libere, quite o comente esta funcionalidad.
Si tiene un método de caballo de batalla, como un aleatorizador, le sugiero que cree un paquete "Toolbox". Todos los codificadores deben tener uno, luego, cuando quiera usarlo en un .java, ¡simplemente impórtelo!
fuente
No existe una variable verdaderamente global en Java. Cada variable estática debe pertenecer a alguna clase (como System.out), pero cuando haya decidido en qué clase entrará, puede consultarla desde cualquier lugar cargado por el mismo cargador de clases.
Tenga en cuenta que las variables estáticas siempre deben protegerse al actualizar para evitar condiciones de carrera.
fuente
De esta manera puede acceder a ellos con
GlobalClass.x
yGlobalClass.s
fuente
Puedes llamar a donde quieras:
fuente
Como probablemente adivine por la respuesta, no hay variables globales en Java y lo único que puede hacer es crear una clase con miembros estáticos:
Puedes usarlo en
Global.a
otro lugar. Sin embargo, si usa Java 1.5 o superior, puede usar laimport static
magia para que se vea aún más como una variable global real:Y voilà !
Ahora, esto está lejos de ser una mejor práctica, como puede ver en los comerciales: no haga esto en casa
fuente
No hay variables globales en Java, pero hay clases globales con campos públicos. Puede usar la función de importación estática de java 5 para que se vea casi como variables globales.
fuente
Generalmente, la variable global (supongo que la está comparando con C, Cpp) se define como
public static final
me gusta
Los ENUM también son útiles en tal escenario:
Por ejemplo
Calendar.JANUARY
)fuente
final
pero ciertamente depende de cómo quieras compartir, dónde estás usando y todo,CODE
en este ejemplo? ¿Dónde se define?Crear un archivo independiente, por ejemplo. Example.java para usar la primera solución, está bien. Puede hacerlo también dentro de la aplicación, por ejemplo, si las variables globales son especiales para su aplicación actual, etc.
Crea una clase al principio y declara tus variables allí:
Luego puede acceder a estas variables, utilizándolas como 'Globals.month_number', etc., desde cualquier lugar de su aplicación.
fuente
Si necesita actualizar la propiedad global, se puede usar una clase de contenedor getter / setter simple como variable global. Un ejemplo típico se muestra a continuación.
fuente
Siguiendo el concepto, las variables globales, también conocidas como variables de instancia, son las variables de nivel de clase, es decir, se definen dentro de una clase pero fuera de los métodos. Para que estén disponibles por completo y usarlos directamente, proporcione la palabra clave estática. Entonces, si estoy escribiendo un programa para una operación aritmética simple y requiere un par de números, entonces dos variables de instancia se definen como tales:
Además, el uso de palabras clave estáticas antes de las variables de instancia nos permite no especificar tipos de datos para las mismas variables una y otra vez. Simplemente escriba la variable directamente.
fuente
static
"no los hace disponibles por completo". El primer párrafo no tiene sentido. El ejemplo es una mala práctica.En general, Java no tiene ninguna variable global. Aparte de las variables locales, todas las variables entran dentro del alcance de cualquier clase definida en el programa. Podemos tener variables estáticas para tener el alcance de las variables globales.
fuente
sin
static
esto también es posible:fuente
La programación orientada a objetos se construye con el entendimiento de que el alcance de las variables es muy exclusivo del objeto de clase que encapsula esas variables.
El problema con la creación de "variables globales" es que no es estándar de la industria para Java. No es un estándar de la industria porque permite que múltiples clases manipulen datos asincronizados, si está ejecutando una aplicación multiproceso, esto se vuelve un poco más complicado y peligroso en términos de seguridad de subprocesos. Hay varias otras razones por las cuales el uso de variables globales no es efectivo, pero si desea evitar eso, le sugiero que recurra a la Programación Orientada a Aspectos .
La Programación Orientada a Aspectos niega este problema al poner a la clase padre a cargo del alcance a través de algo llamado "consejos", que agrega un comportamiento adicional al código sin modificarlo realmente. Ofrece soluciones a problemas transversales o uso de variables globales.
Spring es un marco de Java que utiliza AOP, y aunque se usa tradicionalmente para aplicaciones web, la aplicación central se puede usar universalmente en todo el marco de Java (8.0 incluido). Esta podría ser una dirección que desea explorar más.
fuente
Entendiendo el problema
Considero la calificación de la variable global como una variable a la que se puede acceder y cambiar en cualquier parte del código sin preocuparse por la llamada estática / instancia o pasar cualquier referencia de una clase a otra.
Usualmente si tienes clase A
y desea acceder y actualizar
myvar
en una clase B,necesitará tener una referencia de una instancia de la clase A y actualizar el valor en la clase B de esta manera:
Solución
Entonces, mi solución a esto, (incluso si no estoy seguro de si es una buena práctica), es usar un singleton:
Ahora puede obtener la instancia única global en cualquier lugar con:
fuente
fuente
Para definir la variable global, puede utilizar palabras clave estáticas
ahora puede acceder a ayb desde cualquier lugar llamando
Tienes razón ... especialmente en J2ME ... Puedes evitar NullPointerException poniendo dentro de tu constructor MidLet (inicialización de proggy) esta línea de código:
Esto asegura que las Herramientas se asignarán antes de cualquier instrucción que lo use.
¡Eso es!
fuente