0Pricing
Java Academy · Lección

Campos estáticos y constantes

Use campos estáticos para el estado compartido, constantes con static final e inicializadores estáticos.

Campos estáticos y constantes es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

Campos estáticos y constantes

Los campos estáticos pertenecen a la clase, no a las instancias. Se comparten entre todos los objetos de la clase. Las constantes combinan static y final para crear valores inmutables a nivel de clase.

Campos estáticos frente a campos de instancia

Un campo de instancia tiene una copia independiente por objeto. Un campo estático tiene una única copia compartida por todos los objetos de la clase.

class Counter {
    private static int totalCount = 0;  // shared across all instances
    private int instanceId;              // unique per instance

    Counter() {
        totalCount++;
        instanceId = totalCount;
    }

    static int getTotalCount() { return totalCount; }
    int getInstanceId()        { return instanceId; }
}

Counter c1 = new Counter();
Counter c2 = new Counter();
Counter c3 = new Counter();

System.out.println(Counter.getTotalCount()); // 3
System.out.println(c1.getInstanceId());       // 1
System.out.println(c3.getInstanceId());       // 3

Constantes con static final

Declare las constantes como public static final. Por convención, utilizan SCREAMING_SNAKE_CASE.

class MathConstants {
    public static final double PI      = 3.141592653589793;
    public static final double E       = 2.718281828459045;
    public static final double GOLDEN  = 1.618033988749895;
    public static final int    PRIMES[] = {2, 3, 5, 7, 11, 13};
}

// Access without an instance
System.out.println(MathConstants.PI);

// Constants on domain classes
class HttpStatus {
    public static final int OK        = 200;
    public static final int NOT_FOUND = 404;
    public static final int SERVER_ERR = 500;
}

Bloques de inicialización estáticos

Cuando una constante requiere una inicialización compleja, utilice un bloque de inicialización estático que se ejecute una vez cuando se cargue la clase.

import java.util.*;

class Config {
    public static final Map<String, String> DEFAULTS;

    static {
        Map<String, String> map = new HashMap<>();
        map.put("timeout",  "30");
        map.put("maxRetry", "3");
        map.put("logLevel", "INFO");
        DEFAULTS = Collections.unmodifiableMap(map);
    }
}

System.out.println(Config.DEFAULTS.get("timeout")); // 30

Patrón de contador estático

Los campos estáticos se utilizan habitualmente para generar identificadores, contar métricas o almacenar cachés compartidas.

import java.util.concurrent.atomic.AtomicLong;

class Order {
    private static final AtomicLong ID_SEQUENCE = new AtomicLong(1000);

    private final long id;
    private final String item;

    Order(String item) {
        this.id   = ID_SEQUENCE.getAndIncrement();
        this.item = item;
    }

    long getId()   { return id; }
    String getItem() { return item; }
}

Order o1 = new Order("Laptop");
Order o2 = new Order("Mouse");
System.out.println(o1.getId()); // 1000
System.out.println(o2.getId()); // 1001

Singleton mediante un campo estático

Un campo estático contiene la única instancia de un Singleton. Utilice la inicialización diferida para las clases que quizá no siempre sean necesarias.

class DatabasePool {
    private static volatile DatabasePool instance;
    private final int maxConnections;

    private DatabasePool() { this.maxConnections = 20; }

    public static DatabasePool getInstance() {
        if (instance == null) {
            synchronized (DatabasePool.class) {
                if (instance == null)
                    instance = new DatabasePool();
            }
        }
        return instance;
    }

    public int getMaxConnections() { return maxConnections; }
}

System.out.println(DatabasePool.getInstance().getMaxConnections()); // 20

Importación estática

import static permite utilizar miembros estáticos sin el prefijo del nombre de la clase; resulta útil para constantes y métodos de utilidad.

import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;

// Without import static: Math.PI * Math.pow(r, 2)
double radius = 5.0;
double area = PI * pow(radius, 2);
System.out.printf("Area: %.2f%n", area); // 78.54

// Caution: overuse of static imports hurts readability
// Acceptable for: Math.*, Assert.* in tests, TimeUnit

Seguridad de los campos estáticos entre hilos

Los campos estáticos compartidos entre hilos requieren sincronización o tipos atómicos para evitar condiciones de carrera.

import java.util.concurrent.atomic.*;

class RequestMetrics {
    private static final AtomicLong requestCount  = new AtomicLong(0);
    private static final AtomicLong totalLatencyMs = new AtomicLong(0);

    public static void record(long latencyMs) {
        requestCount.incrementAndGet();
        totalLatencyMs.addAndGet(latencyMs);
    }

    public static double averageLatency() {
        long count = requestCount.get();
        return count == 0 ? 0 : (double) totalLatencyMs.get() / count;
    }
}
RequestMetrics.record(45);
RequestMetrics.record(120);
System.out.println(RequestMetrics.averageLatency()); // 82.5

Campos estáticos mutables: riesgos

Los campos estáticos mutables son peligrosos: el estado global mutable es difícil de probar, no es seguro para los hilos si no se gestiona con cuidado y crea un acoplamiento oculto entre clases.

// BAD: mutable static state
class GlobalConfig {
    public static String environment = "dev"; // mutable global!
}
// Any code anywhere can change GlobalConfig.environment
// Very hard to test, unexpected interactions

// BETTER: immutable constant
class GlobalConfig2 {
    public static final String ENVIRONMENT =
        System.getenv().getOrDefault("APP_ENV", "dev");
}

// BEST: inject via constructor (dependency injection)
class Service {
    private final String environment;
    Service(String environment) { this.environment = environment; }
}

Antipatrón de interfaz de constantes

No se recomienda utilizar una interfaz para almacenar constantes (el antipatrón de la «interfaz de constantes»). Utilice en su lugar una clase con un constructor privado.

// BAD: constant interface — pollutes the namespace of implementing classes
interface FinancialConstants {
    double TAX_RATE = 0.08;  // implicitly public static final
}

// GOOD: utility class for constants
final class FinancialConstants2 {
    private FinancialConstants2() {} // prevent instantiation

    public static final double TAX_RATE  = 0.08;
    public static final double VAT_RATE  = 0.20;
    public static final int    MAX_ITEMS = 100;
}
System.out.println(FinancialConstants2.TAX_RATE); // 0.08

Práctica: indicadores de funcionalidad mediante constantes

Uso de constantes booleanas static final como indicadores de funcionalidad en tiempo de compilación; el compilador JIT elimina las ramas inalcanzables.

class Features {
    public static final boolean ENABLE_ANALYTICS   = true;
    public static final boolean ENABLE_AI_SEARCH    = false;
    public static final boolean DEBUG_MODE          =
        "true".equals(System.getenv("DEBUG"));
}

// The JIT eliminates this if-block when ENABLE_AI_SEARCH is false:
if (Features.ENABLE_AI_SEARCH) {
    System.out.println("Running AI search...");
}

if (Features.DEBUG_MODE) {
    System.out.println("[DEBUG] Request received");
}

Comprobación rápida

¿Cuál es la diferencia entre un campo estático y un campo de instancia?

Repaso: campos estáticos y constantes

Conceptos clave:

  • Los campos estáticos pertenecen a la clase: hay una única copia compartida por todas las instancias
  • Constantes: public static final UPPER_SNAKE_CASE
  • Utilice bloques de inicialización estáticos para las constantes que requieren una inicialización compleja
  • Prefiera AtomicLong/AtomicInteger para los campos estáticos mutables en código concurrente
  • Evite los campos estáticos mutables: crean un estado global oculto que es difícil de probar
  • Utilice una clase no instanciable (con un constructor privado) para las constantes, en lugar de una interfaz

Preguntas frecuentes

¿La lección «Campos estáticos y constantes» es gratis?

Sí — el texto completo de «Campos estáticos y constantes» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Campos estáticos y constantes»?

Use campos estáticos para el estado compartido, constantes con static final e inicializadores estáticos. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Campos estáticos y constantes»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Reglas de sobrecarga de métodos
  2. Parámetros varargs
  3. Campos estáticos y constantes
  4. Clases de utilidades y métodos de fábrica estáticos
← Volver a Java Academy