¿Qué hace la palabra clave “estática” en una clase?

Para ser específico, estaba intentando este código:

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

Pero dio el error

No se puede acceder al campo no estático en el método estático principal

Así que cambié la statement del clock a esto:

 static Clock clock = new Clock(); 

Y funcionó. ¿Qué significa colocar esa palabra clave antes de la statement? ¿Qué es exactamente lo que hará y / o restringirá en términos de lo que se puede hacer con ese objeto?

static miembros static pertenecen a la clase en lugar de a una instancia específica.

Significa que solo existe una instancia de un campo static [1] incluso si crea un millón de instancias de la clase o si no crea ninguna. Será compartido por todas las instancias.

Dado que static métodos static tampoco pertenecen a una instancia específica, no pueden referirse a los miembros de la instancia (¿cómo sabría a qué clase de instancia de Hello desea hacer referencia?). static miembros static solo pueden referirse a miembros static . Los miembros de instancia pueden, por supuesto, acceder a miembros static .

Nota al margen: por supuesto, static miembros static pueden acceder a los miembros de la instancia a través de una referencia de objeto .

Ejemplo:

 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]: según las características del tiempo de ejecución, puede ser uno por ClassLoader o AppDomain o thread, pero eso está al lado del punto.

Significa que solo hay una instancia de “reloj” en Hola, no una por cada instancia separada de la clase “Hola”, o más, por lo tanto, significa que habrá una referencia de “reloj” compartida comúnmente entre todas las instancias de la clase “Hola”

Entonces, si hicieras un “nuevo saludo” en cualquier parte de tu código: A- en el primer escenario (antes del cambio, sin usar “estático”), crearía un nuevo reloj cada vez que se llame un “nuevo saludo”, pero B- en el segundo escenario (después del cambio, usando “estático”), cada instancia de “nuevo saludo” aún compartiría y usaría la referencia inicial y el mismo “reloj” que se creó primero.

A menos que necesites “reloj” en algún lugar fuera de la línea principal, esto funcionaría igual de bien:

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

La palabra clave static significa que algo (un campo, método o clase anidada) está relacionado con el tipo en lugar de cualquier instancia particular del tipo. Entonces, por ejemplo, uno llama a Math.sin(...) sin ninguna instancia de la clase Math , y de hecho no puede crear una instancia de la clase Math .

Para obtener más información, consulte el fragmento relevante del Tutorial de Java de Oracle .


Nota al margen

Desafortunadamente, Java le permite acceder a los miembros estáticos como si fueran miembros de instancia, por ejemplo

 // Bad code! Thread.currentThread().sleep(5000); someOtherThread.sleep(5000); 

Eso hace que parezca que el modo de sleep es un método de instancia, pero en realidad es un método estático: siempre hace que el hilo actual duerma. Es una mejor práctica dejar esto en claro en el código de llamada:

 // Clearer Thread.sleep(5000); 

La palabra clave static en Java significa que la variable o función se comparte entre todas las instancias de esa clase, ya que pertenece al tipo , no a los objetos mismos.

Entonces, si tiene una variable: private static int i = 0; y lo incrementa ( i++ ) en una instancia, el cambio se reflejará en todas las instancias. ahora seré 1 en todas las instancias.

Los métodos estáticos se pueden usar sin instanciar un objeto.

Uso básico de miembros estáticos …

 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 } 

Así es como puede tener valores compartidos en todos los miembros de la clase sin enviar la clase de clase Hola a otra clase. Y con estática no es necesario crear una instancia de clase.

 Hello hello = new Hello(); hello.staticValue = "abc"; 

Puede llamar a valores o métodos estáticos por nombre de clase:

 Hello.staticValue = "abc"; 

Estático significa que no tiene que crear una instancia de la clase para usar los métodos o variables asociados con la clase. En su ejemplo, puede llamar:

 Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class 

directamente, en lugar de:

 Hello h = new Hello(); h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable 

Desde dentro de un método estático (que pertenece a una clase) no puede acceder a ningún miembro que no sea estático, ya que sus valores dependen de la creación de instancias de la clase. Un objeto Clock no estático, que es un miembro de instancia, tendría un valor / referencia diferente para cada instancia de su clase Hello y, por lo tanto, no podría acceder desde la parte estática de la clase.

Estático en Java:

Static es un modificador de no acceso. La palabra clave estática pertenece a la clase de instancia de la clase. se puede utilizar para adjuntar una variable o método a una clase.

La palabra clave estática PUEDE usarse con:

Método

Variable

Clase anidada dentro de otra clase

Bloque de inicialización

NO PUEDE ser utilizado con:

Clase (no anidada)

Constructor

Interfaces

Método Clase interna local (Diferencia luego clase anidada)

Métodos de clase interna

Variables de instancia

Variables locales

Ejemplo:

Imagine el siguiente ejemplo que tiene una variable de instancia llamada conteo que en incrementado en el constructor:

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

Salida:

1 1 1

Como la variable de instancia obtiene la memoria en el momento de la creación del objeto, cada objeto tendrá la copia de la variable de instancia, si se incrementa, no se reflejará en otros objetos.

Ahora si cambiamos el recuento de variables de instancia a uno estático , el progtwig producirá resultados diferentes:

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

Salida:

1 2 3

En este caso, la variable estática obtendrá la memoria solo una vez, si algún objeto cambia el valor de la variable estática, retendrá su valor.

Estático con final:

La variable global que se declara como final y estática permanece sin cambios para toda la ejecución. Porque los miembros estáticos se almacenan en la memoria de la clase y se cargan solo una vez en toda la ejecución. Son comunes a todos los objetos de la clase. Si declara variables estáticas como finales, cualquiera de los objetos no puede cambiar su valor ya que es final. Por lo tanto, las variables declaradas como finales y estáticas a veces se denominan Constantes. Todos los campos de las interfaces se conocen como constantes, ya que son finales y estáticos por defecto.

enter image description here

Imagen del recurso: Final estático

Esta discusión hasta ahora ha ignorado las consideraciones del cargador de clases. Estrictamente hablando, los campos estáticos de Java se comparten entre todas las instancias de una clase para un cargador de clases determinado.

Para agregar a las respuestas existentes, déjame intentar con una imagen:

Se aplica una tasa de interés del 2% a TODAS las cuentas de ahorro. Por lo tanto, es estático .

Un equilibrio debe ser individual , por lo que no es estático.

enter image description here

Se puede asignar un campo a la clase o a una instancia de una clase. Por defecto, los campos son variables de instancia. Al usar static el campo se convierte en una variable de clase, por lo tanto, hay uno y solo un clock . Si realiza cambios en un lugar, es visible en todas partes. Los elementos de instancia se cambian independientemente el uno del otro.

En Java, la palabra clave static se puede considerar simplemente como lo siguiente:

“sin consideración o relación con ninguna instancia en particular”

Si piensa en static de esta manera, es más fácil entender su uso en los diversos contextos en los que se encuentra:

  • Un campo static es un campo que pertenece a la clase en lugar de a una instancia particular

  • Un método static es un método que no tiene noción de this ; se define en la clase y no conoce ninguna instancia particular de esa clase a menos que se le pase una referencia

  • Una clase de miembro static es una clase anidada sin ninguna noción o conocimiento de una instancia de su clase adjunta (a menos que se le pase una referencia a una instancia de clase adjunta)

Static hace que el miembro del reloj sea un miembro de la clase en lugar de un miembro de la instancia. Sin la palabra clave estática, necesitaría crear una instancia de la clase Hello (que tiene una variable de miembro de reloj), por ej.

 Hello hello = new Hello(); hello.clock.sayTime(); 

los métodos estáticos no usan ninguna variable de instancia de la clase en la que están definidos. Una muy buena explicación de la diferencia se puede encontrar en esta página

He desarrollado un gusto por los métodos estáticos (solo, si es posible) en clases “auxiliares”.

La clase de llamada no necesita crear otra variable de miembro (instancia) de la clase auxiliar. Simplemente llama a los métodos de la clase de ayuda. También se mejora la clase auxiliar porque ya no necesita un constructor y no necesita variables de miembro (instancia).

Probablemente haya otras ventajas.

La palabra clave static se usa para indicar que un campo o método pertenece a la clase en sí y no a la instancia. Usando su código, si el objeto Clock es estático, todas las instancias de la clase Hello compartirán este miembro (campo) de datos Clock en común. Si lo hace no estático, cada instancia individual de Hello puede tener un campo Clock único.

El problema es que agregó un método principal a su clase Hello para que pueda ejecutar el código. El problema aquí es que el método principal es estático y, como tal, no puede referirse a campos o métodos no estáticos dentro de él. Puedes resolver esto de dos maneras:

  1. Haga que todos los campos y métodos de la clase Hello estén estáticos para que puedan ser referidos dentro del método principal . Esto realmente no es algo bueno que hacer (o la razón incorrecta para hacer un campo y / o un método estático)
  2. Cree una instancia de su clase Hello dentro del método principal y acceda a todos sus campos y métodos de la manera en que estaban destinados en primer lugar.

Para ti, esto significa el siguiente cambio en tu código:

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

También se puede pensar en miembros estáticos que no tienen un puntero “this”. Se comparten entre todas las instancias.

Comprender los conceptos estáticos

 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 */ } } 

Segunda clase

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

main() es un método estático que tiene dos restricciones fundamentales:

  1. El método estático no puede usar un miembro de datos no estáticos ni llamar directamente al método no estático.
  2. this() y super() no se pueden usar en contexto estático.

     class A { int a = 40; //non static public static void main(String args[]) { System.out.println(a); } } 

Salida: error de tiempo de comstackción

Las variables estáticas solo se puede acceder en métodos estáticos, por lo que cuando declaramos las variables estáticas esos métodos getter y setter serán métodos estáticos

métodos estáticos es un nivel de clase al que podemos acceder usando el nombre de clase

A continuación se muestra un ejemplo de los generadores y ajustadores de variables estáticas:

 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; } } 

Cuando ejecute algún proyecto, primero cargue cosas estáticas (variables, métodos, bloques …).

Cuando ejecute este método principal del proyecto cargue primero. Porque su static method . Luego mira el objeto "a" object .Pero el objeto a no define aún. Porque no es estático. Entonces ven como este error.