Bloques estáticos
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 17 de 87.
A veces es necesario inicializar variables estáticas con una lógica que es más compleja que una simple asignación. Un bloque estático (también llamado inicializador estático) se ejecuta una vez cuando la clase se carga por primera vez, antes de que se cree cualquier objeto o se llame a cualquier método estático.
public class DatabaseConfig {
private static String connectionString;
private static int maxConnections;
static {
// Lógica de inicialización compleja
connectionString = "jdbc:mysql://localhost:3306/mydb";
maxConnections = 10;
System.out.println("Database configuration loaded");
}
}El bloque estático se ejecuta automáticamente cuando la clase se carga en memoria. Esto sucede solo una vez, independientemente de cuántos objetos crees. Es perfecto para la inicialización que requiere múltiples sentencias, cálculos o lógica condicional.
Puedes tener múltiples bloques estáticos en una clase, y se ejecutan en el orden en que aparecen:
public class AppSettings {
private static int[] values;
static {
values = new int[5];
}
static {
for (int i = 0; i < values.length; i++) {
values[i] = i * 10;
}
}
}Los bloques estáticos se utilizan comúnmente para inicializar arreglos o colecciones estáticas, establecer valores de configuración que requieren cálculos y realizar tareas de configuración de una sola vez a nivel de clase.
Desafío
FácilVamos a construir un sistema GameConfig que utiliza bloques estáticos para inicializar la configuración del juego cuando la clase se carga por primera vez. Esto es perfecto para configuraciones que necesitan ser calculadas o establecidas una sola vez antes de que se creen objetos del juego.
Crearás dos archivos para organizar tu código:
GameConfig.java: Crea una clase de configuración que inicializa sus ajustes usando bloques estáticos:- Un arreglo estático privado
levelThresholds(int[]) que almacena la puntuación necesaria para alcanzar cada nivel - Una variable estática privada
maxLevel(int) que almacena el número total de niveles - Una variable estática privada
configLoaded(boolean) para rastrear si la inicialización ocurrió - Usa un bloque estático para inicializar
maxLevela 5 e imprimir"Initializing game configuration..." - Usa un segundo bloque estático para crear el arreglo
levelThresholdscon un tamaño igual amaxLevel, luego llénalo de modo que cada nivel requieralevel * 100puntos (el nivel 1 necesita 100, el nivel 2 necesita 200, etc.), y establececonfigLoadedatrue - Un método estático
getThreshold(int level)que devuelve el umbral de puntuación para ese nivel (los niveles están indexados en 1) - Un método estático
getMaxLevel()que devuelve el nivel máximo - Un método estático
isConfigLoaded()que devuelve si la configuración ha sido cargada
- Un arreglo estático privado
Main.java: Demuestra que los bloques estáticos se ejecutan automáticamente cuando se accede a la clase. Recibirás una entrada: un número de nivel para consultar. Imprime cuatro líneas:Config loaded: trueoConfig loaded: falseMax level: [maxLevel]Level [level] threshold: [threshold]Level 1 threshold: [threshold](siempre muestra el nivel 1 también)
Recibirás una entrada: el número de nivel (int) a consultar.
Observa cómo el mensaje de inicialización se imprime antes de que se ejecute cualquier código de tu Main: ¡ese es el bloque estático ejecutándose cuando la clase se carga por primera vez!
Hoja de referencia
Un bloque estático (o inicializador estático) se ejecuta una vez cuando la clase se carga por primera vez, antes de que se cree cualquier objeto o se llame a métodos estáticos. Se utiliza para lógica de inicialización compleja que requiere múltiples sentencias.
public class Example {
private static String value;
static {
// Lógica de inicialización
value = "initialized";
System.out.println("Static block executed");
}
}Los bloques estáticos se ejecutan automáticamente cuando la clase se carga en memoria, solo una vez independientemente de cuántos objetos se creen.
Puedes tener múltiples bloques estáticos en una clase. Se ejecutan en el orden en que aparecen:
public class Example {
private static int[] values;
static {
values = new int[5];
}
static {
for (int i = 0; i < values.length; i++) {
values[i] = i * 10;
}
}
}Los usos comunes incluyen la inicialización de arreglos o colecciones estáticas, la configuración de valores de configuración que requieren cálculos y la realización de tareas de configuración únicas a nivel de clase.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int level = scanner.nextInt();
// TODO: Acceder a GameConfig para demostrar la ejecución del bloque estático
// Los bloques estáticos en GameConfig se ejecutarán automáticamente cuando accedas por primera vez a la clase
// TODO: Imprimir si la configuración está cargada
// Formato: "Config loaded: true" o "Config loaded: false"
// TODO: Imprimir el nivel máximo
// Formato: "Max level: [maxLevel]"
// TODO: Imprimir el umbral para el nivel de entrada
// Formato: "Level [level] threshold: [threshold]"
// TODO: Imprimir el umbral para el nivel 1
// Formato: "Level 1 threshold: [threshold]"
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator