¿Qué hace la palabra clave "estática" en una clase?
Para ser específico, estaba probando 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
Entonces cambié la declaración de clock
a esto:
static Clock clock = new Clock();
Y funcionó. ¿Qué significa poner esa palabra clave antes de la declaración? ¿Qué hará y/o restringirá exactamente en términos de lo que se puede hacer con ese objeto?
static
los miembros pertenecen a la clase en lugar de a una instancia específica.
Significa que solo static
existe una instancia de un campo [1] incluso si creas un millón de instancias de la clase o no creas ninguna. Será compartido por todas las instancias.
Dado que static
los métodos tampoco pertenecen a una instancia específica, no pueden hacer referencia a miembros de la instancia. En el ejemplo dado, main
no sabe a qué instancia de la Hello
clase (y por lo tanto a qué instancia de la Clock
clase) debe hacer referencia. static
Los miembros sólo pueden referirse a static
miembros. Los miembros de la instancia pueden, por supuesto, acceder a static
los miembros.
Nota al margen: por supuesto, static
los miembros 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]: Dependiendo de las características del tiempo de ejecución, puede ser uno por ClassLoader o AppDomain o hilo, pero eso no viene al caso.
Significa que solo hay una instancia de "reloj" en Hello, no una por cada instancia separada de la clase "Hello", o más aún, significa que habrá una referencia de "reloj" comúnmente compartida entre todas las instancias de la clase "Hola".
Entonces, si hiciera un "nuevo Hola" en cualquier parte de su código: A- en el primer escenario (antes del cambio, sin usar "estático"), se crearía un nuevo reloj cada vez que se llame a un "nuevo Hola", pero B- en el segundo escenario (después del cambio, usando "estático"), cada instancia de "nueva Hola" aún compartiría y usaría la misma referencia de "reloj" inicial creada por primera vez.
A menos que necesites un "reloj" en algún lugar fuera de main, esto funcionaría igual de bien:
package hello;
public class Hello
{
public static void main(String args[])
{
Clock clock=new Clock();
clock.sayTime();
}
}
La static
palabra clave significa que algo (un campo, método o clase anidada) está relacionado con el tipo en lugar de con cualquier instancia particular del tipo. Entonces, por ejemplo, uno llama Math.sin(...)
sin ninguna instancia de la Math
clase y, de hecho, no puede crear una instancia de la Math
clase.
Para obtener más información, consulte la parte relevante del Tutorial de Java de Oracle .
Nota al margen
Desafortunadamente, Java le permite acceder a miembros estáticos como si fueran miembros de instancia, por ejemplo
// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
Eso hace que parezca unsleep
método de instancia, pero en realidad es un método estático: siempre hace que el hilo actual entre en suspensión. Es una mejor práctica dejar esto claro en el código de llamada:
// Clearer
Thread.sleep(5000);