🧲 Variables, métodos y clases estáticas en Java
Idea clave:
staticsignifica “de la clase”, no “del objeto”.
Una clase, método o campo estático se puede usar sin crear objetos de esa clase.
En esta página veremos:
- 🧱 Diferencias entre miembros estáticos y de instancia
- 🧊 Constantes de clase (
static final) - 🧮 Métodos estáticos (como
main) - 🧮 Métodos de instancia
- ❓ ¿Método estático o de instancia?
- 🧩 Clases internas estáticas
- ⚡ Bloques estáticos de inicialización
- 📦 Imports estáticos
- 🆕 Detalles modernos de Java relacionados con
static - 🚨 Errores típicos con
static
🧱 Variables de instancia vs variables estáticas
🔹 Variables de instancia
Son los atributos normales de un objeto:
- Pertenecen a cada objeto.
- Cada objeto tiene su propia copia.
- Representan el estado de ese objeto.
class Persona {
private String nombre; // variable de instancia
public Persona(String nombre) {
this.nombre = nombre;
}
public void printNombre() {
System.out.println(nombre);
}
}
public class Main {
public static void main(String[] args) {
Persona p1 = new Persona("Patricia");
Persona p2 = new Persona("Maxi");
p1.printNombre(); // imprime Patricia
p2.printNombre(); // imprime Maxi
}
}
👉 Cada persona tiene su propio nombre.
🔸 Variables estáticas
Son compartidas por todas las instancias de la clase, porque pertenecen a la clase:
- Se declaran con la palabra reservada
static. - Solo existe UNA copia en memoria, aunque haya muchos objetos.
- Todas las instancias ven el mismo valor.
- Se suelen usar poco: solo cuando de verdad tiene sentido compartir el dato.
public class Contador {
private static int totalObjetos = 0; // variable estática
private String nombre; // variable de instancia
public Contador(String nombre) {
this.nombre = nombre;
totalObjetos++; // cada vez que se crea uno, suma 1
}
public void printInfo() {
System.out.println("Soy " + nombre +
" y se han creado " + totalObjetos + " objetos.");
}
}
public class Main {
public static void main(String[] args) {
Contador c1 = new Contador("Primero");
Contador c2 = new Contador("Segundo");
c1.printInfo(); // Soy Primero y se han creado 2 objetos.
c2.printInfo(); // Soy Segundo y se han creado 2 objetos.
}
}
👉 totalObjetos es de la clase (compartido).
👉 nombre es de cada objeto.
📊 Resumen rápido
| Tipo de miembro | ¿De quién es? | Nº de copias | Acceso habitual |
|---|---|---|---|
| Variable de instancia | De cada objeto | Una por objeto | objeto.atributo |
| Variable estática | De la clase | Una para toda la clase | NombreClase.atributo o desde métodos estáticos |
💎 Constantes de clase (static final)
Una constante de clase es un campo:
static➜ es de la clase, hay una sola copia.final➜ no se puede cambiar su valor (constante).
public class Juego {
public static final int MODO_UN_JUGADOR = 1;
public static final int MODO_MULTIJUGADOR = 2;
private int modo;
public Juego(int modo) {
this.modo = modo;
}
public static void main(String[] args) {
Juego juego = new Juego(Juego.MODO_MULTIJUGADOR);
}
}
✅ Ventajas:
- Ahorra memoria: solo hay una copia de la constante.
- Se puede usar sin crear objetos.
- Hace el código más legible (
MODO_MULTIJUGADORes más claro que2).
⚙️ Métodos estáticos
Un método estático:
- Se declara con
static. - No puede acceder directamente a atributos ni métodos de instancia.
- Se puede llamar con
NombreClase.metodo()o directamentemetodo()si está en la misma clase. - Se suele usar para:
- Funciones auxiliares / utilidades
- Cálculos que no dependen del estado de ningún objeto.
- El famoso
main.
class Calculadora {
public static int sumar(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
int resultado = Calculadora.sumar(5, 6);
System.out.println(resultado); // 11
}
}
🚫 Dentro de un método estático:
- No puedes usar
this. - No puedes acceder directamente a variables de instancia.
class Ejemplo {
private int numero = 10;
public static void metodoEstatico() {
// System.out.println(numero); // ❌ ERROR: numero es de instancia
}
}
🧍♀️ Métodos de instancia
- Necesitan un objeto para usarse.
- Pueden acceder tanto a:
- Variables y métodos de instancia
- Como a variables y métodos estáticos
class Cuenta {
private double saldo;
private static double interesAnual = 0.02;
public Cuenta(double saldoInicial) {
this.saldo = saldoInicial;
}
public void aplicarInteres() { // método de instancia
saldo += saldo * interesAnual; // usa saldo (instancia) e interesAnual (estático)
}
public static void cambiarInteres(double nuevoInteres) { // método estático
interesAnual = nuevoInteres;
}
}
❓ ¿Método estático o de instancia?
Regla práctica:
🔍 Pregunta: “¿Este método necesita datos del objeto (
this)?”
- ✅ Sí ➜ Método de instancia.
- ❌ No ➜ Método estático.
Ejemplos típicos de métodos estáticos:
- Conversión de tipos (
parseInt, etc.). - Funciones matemáticas (
Math.sqrt,Math.random…). - Utilidades que no dependen del estado (
Collections.sort, etc.).
🧱 Clases internas estáticas
Java no permite que una clase “normal” externa sea estática, pero sí permite que una clase interna lo sea.
public class Contenedor {
static int valorEstatico = 42;
int valorInstancia = 7;
public static class Interna {
public static void imprimir() {
System.out.println(valorEstatico); // ✅ puede acceder a estáticos de Contenedor
// System.out.println(valorInstancia); // ❌ NO puede acceder a no estáticos
}
}
public static void main(String[] args) {
Contenedor.Interna.imprimir();
}
}
📌 Recuerda:
- Una clase interna estática:
- No necesita una instancia de la clase externa.
- Solo puede acceder a miembros estáticos de la clase externa.
⚡ Bloques estáticos de inicialización
Un bloque estático se ejecuta una sola vez, cuando la clase se carga en memoria.
Se usa para inicializar campos estáticos de forma más compleja que con una simple asignación.
public class Configuracion {
private static String URL_BD;
static {
// Este código se ejecuta UNA sola vez, al cargarse la clase
URL_BD = "jdbc:mysql://localhost:3306/mi_bd";
System.out.println("Inicializando configuración...");
}
public static String getUrlBd() {
return URL_BD;
}
}
⚠️ Úsalos con moderación: pueden hacer que el código sea más difícil de seguir.
📦 Imports estáticos
Desde Java 5 se pueden importar miembros estáticos de otras clases:
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
public class Circulo {
public static void main(String[] args) {
double radio = 3;
double longitud = 2 * PI * radio; // uso PI sin Math.
double raiz = sqrt(16); // uso sqrt sin Math.
}
}
✅ Útil para:
- Test unitarios (métodos estáticos de
Assertions,Assert, etc.). - Código matemático.
⚠️ No abuses: si llenas un archivo de imports estáticos puede perder legibilidad.
🆕 Detalles modernos de Java relacionados con static
Aunque la palabra static existe desde las primeras versiones de Java, hay algunas novedades o matices modernos:
🧪 Métodos estáticos en interfaces (desde Java 8)
Desde Java 8, una interface puede tener métodos estáticos:
public interface Conversor {
static int aEntero(String valor) {
return Integer.parseInt(valor);
}
}
public class Main {
public static void main(String[] args) {
int n = Conversor.aEntero("123");
System.out.println(n);
}
}
👉 Se llaman con NombreInterfaz.metodoEstatico().
👉 No se heredan como métodos de instancia de las clases que implementan la interfaz.
🔐 Métodos static privados en interfaces (desde Java 9)
También se pueden crear métodos static privados dentro de interfaces para reutilizar código entre otros métodos default o static de la interfaz.
public interface Mensajes {
static void saludar() {
imprimir("Hola");
}
static void despedir() {
imprimir("Adiós");
}
private static void imprimir(String texto) { // método estático privado
System.out.println(texto);
}
}
🚨 Errores típicos con static
- Usar
static“porque sí” - Poner todo como
staticpara “acceder desde main” es una mala práctica. -
Pierdes la gracia de la POO (objetos, estado, encapsulación…).
-
Acceder a miembros de instancia desde un método estático
- Da error de compilación.
-
Solución: crear un objeto y trabajar con él, o convertir el método en método de instancia.
-
Usar variables estáticas para guardar estado “global” sin pensar
-
Puede complicar pruebas, mantenimiento y comportamiento en programas grandes.
-
Confundir constante de clase con literal mágico
- Mejor
static final int MAX_INTENTOS = 3;que usar3suelto por todas partes.
Recuerda: si un método no necesita acceder a datos del objeto, probablemente debería ser estático 😉