La palabra static declara miembros (atributos, métodos y clases anidadas) que están asociados a una clase en vez de a una instancia de la clase.
Atributos Estáticos (static)
A veces resulta útil tener una variable compartida por todas las instancias de una clase. Esta variable podría utilizarse, por ejemplo, como base para la comunicación entre instancias o para llevar el control del número de instancias que se han creado.

El modo compartido se consigue marcando la variable con la palabra static. Este tipo de variables a veces se denominan variables de clase para distinguirlas de los miembros o las variables de instancia, que no se comparten. En este ejemplo, a cada objeto que se crea se le asigna un número de serie exclusivo que empieza desde 1 y continúa en sentido ascendente. Todas las instancias comparten la variable counter por lo que, cuando el constructor de un objeto incrementa counter, el siguiente objeto que se crea recibe el valor incrementado.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Cliente { // Propiedades de instancia private int codigo; private String nombre; private String email; // Propiedades de la clase public static int contador=0; static{ // codigo para inicializar contador } public Cliente() { codigo = contador++; // TODO Auto-generated constructor stub } } |
Si una variable static no se marca como private, es posible acceder a ella desde fuera de la clase. Para hacerlo, no se necesita ninguna instancia de la clase, basta hacer referencia a ella mediante el nombre de la clase.
|
1 2 3 4 5 6 |
public class OtraClase{ public void incremetarenuno(){ Cliente.contador++; } } |
Ejemplo de ejecución en una clase main:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Main { public static void main(String[] args) { System.out.println("Contador : " + Cliente.contador); Cliente c1 = new Cliente("Pedro", "pedro@gmail.com"); System.out.println(c1); System.out.println("Contador : " + Cliente.verContador()); Cliente c2 = new Cliente("Maria", "maria@gmail.com"); System.out.println(c2); System.out.println("Contador : " + Cliente.contador); } } |
Métodos Estáticos (static)
Cuando no hay disponible ninguna instancia de un determinado objeto, es necesario acceder al código del programa. Los métodos marcados con la palabra static pueden utilizarse de esta forma y algunas veces se denominan métodos de clase.
|
1 2 3 4 5 6 7 |
public class UnaClase{ public static int metodoEstatico(int n1, int n2){ int numero = n1+n2; return numero; } } |
Debe acceder a los métodos estáticos utilizando el nombre de la clase en lugar de una referencia al objeto.
De esta forma podemos ejercutar el metodo sin instanciar la clase:
|
1 |
UnaClase.mentodoestatico(6,8); |
Dado que puede llamar a un método static sin necesidad de tener una instancia de la clase a la que pertenece, no existe ningún valor this. Como consecuencia, un método static no puede acceder a ninguna variable salvo a las variables locales, los atributos static y sus parámetros. Cualquier intento de acceder a atributos que no sean estáticos provoca un error de compilación. Los atributos no estáticos se limitan a una instancia y sólo se puede acceder a ellos mediante referencias a esa instancia.

Cuando use métodos estáticos, debe tener en cuenta lo siguiente:
- No es posible sobrescribir un método static pero sí puede ocultarse. Para poder sobrescribir un método, tiene que ser no estático. La existencia de dos métodos estáticos con la misma firma en una jerarquía de clases simplemente significa que son dos métodos de clase independientes. Si se aplica un método de clase a una referencia de objeto, el método llamado será el correspondiente a la clase para la que se haya declarado la variable.
- El método main() es un método static porque JVM no crea ninguna instancia de la clase cuando lo ejecuta. Por tanto, si tiene datos de miembros, debe crear un objeto para acceder a ellos.
Recursos Finales
Cuando declaramos una propiedad final estamos creando una constante. Una constante es una variable que una vez asignado un valor, este no se puede modificar. En el siguiente ejemplo, vemos la propiedad id declarada como final, esta se inicializa en el constructor a partir de un contador estático. Una vez que hemos asignado un valor a la propiedad id este no podrá ser modificado.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Coche { private int kilometros; private final String bastidor; // Atributo estático private string matricula; public Coche(){ this.bastidor = "885485DCV"; // Este dato no podra ser cambiado } } |
Métodos Finales
Cuando declaramos un método como final, este no se puede sobrescribir. En el siguiente ejemplo hemos agregado el método mostrarInformacion a la clase Persona. Dicho método lo hemos declarado como final lo que significa que las subclases de Persona no podrán redefinir este método.
|
1 2 3 4 5 |
public final void mostrarInformacion(){ System.out.println("Matricula: " + matricula + "Bastidor: " + bastidor +...) } |
Clases Finales
Una clase final es una clase que no soporta herencia, esto es, no se puede crear una subclase de ella.