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

Resuelto Ali asked hace 15 años • 22 respuestas

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 clocka 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?

Ali avatar Jan 06 '09 00:01 Ali
Aceptado

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

Significa que solo staticexiste 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 staticlos métodos tampoco pertenecen a una instancia específica, no pueden hacer referencia a miembros de la instancia. En el ejemplo dado, mainno sabe a qué instancia de la Helloclase (y por lo tanto a qué instancia de la Clockclase) debe hacer referencia. staticLos miembros sólo pueden referirse a staticmiembros. Los miembros de la instancia pueden, por supuesto, acceder a staticlos miembros.

Nota al margen: por supuesto, staticlos 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.

Mehrdad Afshari avatar Jan 05 '2009 17:01 Mehrdad Afshari

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();    
    }
}
Paul Tomblin avatar Jan 05 '2009 17:01 Paul Tomblin

La staticpalabra 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 Mathclase y, de hecho, no puede crear una instancia de la Mathclase.

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);
Jon Skeet avatar Jul 04 '2009 06:07 Jon Skeet