← Назад к вопросам
Приведи пример static блока
2.0 Middle🔥 191 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью#ORM и Hibernate
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Приведи пример static блока
Рассмотрим static блоки в Java — это конструкции, которые выполняются один раз при загрузке класса.
Что такое static блок?
Static блок — это блок инициализации, который:
- Выполняется только один раз при загрузке класса
- Выполняется ДО создания первого объекта
- Используется для инициализации static переменных
- Не имеет доступа к instance переменным (только к static)
Базовый пример
public class ConfigLoader {
private static int maxConnections;
private static String appName;
// Static блок выполняется при загрузке класса
static {
System.out.println("ConfigLoader loaded!");
maxConnections = 100;
appName = "MyApp";
}
public static void main(String[] args) {
System.out.println("Max connections: " + maxConnections);
System.out.println("App name: " + appName);
}
}
// Вывод:
// ConfigLoader loaded! (static блок)
// Max connections: 100
// App name: MyApp
Замечаете, что строка "ConfigLoader loaded!" напечаталась ДО содержимого main? Это потому что static блок выполнится раньше.
Реальный пример: инициализация логирования
import java.util.logging.Logger;
import java.util.logging.Level;
public class Application {
private static final Logger LOGGER = Logger.getLogger(Application.class.getName());
private static boolean isProduction;
private static String databaseUrl;
static {
// Читаем переменные окружения при загрузке класса
String env = System.getenv("APP_ENV");
isProduction = "production".equalsIgnoreCase(env);
databaseUrl = isProduction
? "jdbc:postgresql://prod-db.example.com:5432/app"
: "jdbc:h2:mem:testdb";
// Настраиваем логирование
if (isProduction) {
LOGGER.setLevel(Level.WARNING);
} else {
LOGGER.setLevel(Level.FINE);
}
LOGGER.info("Application initialized in " + env + " mode");
LOGGER.info("Database: " + databaseUrl);
}
public static void main(String[] args) {
LOGGER.info("Application started");
}
}
// При запуске в production:
// DATABASE: jdbc:postgresql://prod-db.example.com:5432/app
// Application initialized in production mode
// Application started
Пример 2: инициализация connection pool
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class Database {
private static HikariDataSource dataSource;
private static final int POOL_SIZE = 10;
private static final String DB_URL = "jdbc:postgresql://localhost/mydb";
static {
System.out.println("Initializing database connection pool...");
HikariConfig config = new HikariConfig();
config.setJdbcUrl(DB_URL);
config.setUsername("postgres");
config.setPassword("password");
config.setMaximumPoolSize(POOL_SIZE);
config.setMinimumIdle(2);
config.setConnectionTimeout(10000);
dataSource = new HikariDataSource(config);
System.out.println("Database pool ready with " + POOL_SIZE + " connections");
}
public static HikariDataSource getDataSource() {
return dataSource;
}
}
// Вывод при загрузке:
// Initializing database connection pool...
// Database pool ready with 10 connections
Пример 3: инициализация коллекций
import java.util.*;
public class StatusCodes {
private static final Map<Integer, String> STATUS_MAP;
private static final Set<String> ALLOWED_ROLES;
// Static блок инициализирует Collections
static {
// Инициализация MAP
STATUS_MAP = new HashMap<>();
STATUS_MAP.put(200, "OK");
STATUS_MAP.put(201, "Created");
STATUS_MAP.put(400, "Bad Request");
STATUS_MAP.put(401, "Unauthorized");
STATUS_MAP.put(404, "Not Found");
STATUS_MAP.put(500, "Internal Server Error");
// Инициализация SET
ALLOWED_ROLES = new HashSet<>();
ALLOWED_ROLES.add("ADMIN");
ALLOWED_ROLES.add("USER");
ALLOWED_ROLES.add("MODERATOR");
}
public static String getStatusMessage(int code) {
return STATUS_MAP.getOrDefault(code, "Unknown");
}
public static boolean isValidRole(String role) {
return ALLOWED_ROLES.contains(role);
}
public static void main(String[] args) {
System.out.println(getStatusMessage(404)); // Not Found
System.out.println(isValidRole("ADMIN")); // true
System.out.println(isValidRole("SUPERUSER")); // false
}
}
Пример 4: множественные static блоки
В классе может быть несколько static блоков, они выполняются по порядку:
public class InitializationOrder {
private static int counter = 0;
static {
counter = 1;
System.out.println("Static block 1, counter = " + counter);
}
static {
counter = 2;
System.out.println("Static block 2, counter = " + counter);
}
static {
counter = 3;
System.out.println("Static block 3, counter = " + counter);
}
public static void main(String[] args) {
System.out.println("Main method, counter = " + counter);
}
}
// Вывод:
// Static block 1, counter = 1
// Static block 2, counter = 2
// Static block 3, counter = 3
// Main method, counter = 3
Static блок vs Конструктор
public class Comparison {
private static int staticCounter = 0; // Static переменная
private int instanceCounter = 0; // Instance переменная
// STATIC блок - выполняется один раз при загрузке класса
static {
staticCounter = 100;
System.out.println("Static block executed once");
}
// Конструктор - выполняется каждый раз при создании объекта
public Comparison() {
instanceCounter = 10;
System.out.println("Constructor executed");
}
public static void main(String[] args) {
System.out.println("Before creating objects\n");
Comparison obj1 = new Comparison(); // Конструктор вызовется
System.out.println();
Comparison obj2 = new Comparison(); // Конструктор вызовется ещё раз
System.out.println();
System.out.println("Static counter: " + Comparison.staticCounter);
}
}
// Вывод:
// Static block executed once (один раз)
// Before creating objects
// Constructor executed (первый объект)
// Constructor executed (второй объект)
// Static counter: 100
Практическое применение
1. Инициализация сложных ресурсов
public class EmailService {
private static JavaMailSender mailSender;
static {
SimpleMailMessage message = new SimpleMailMessage();
// Настройка почты один раз
mailSender = createMailSender();
}
private static JavaMailSender createMailSender() {
// Тяжёлая операция инициализации
return null;
}
}
2. Загрузка конфигурации
public class AppConfig {
public static final Properties CONFIG;
static {
CONFIG = new Properties();
try {
CONFIG.load(AppConfig.class.getResourceAsStream("/app.properties"));
} catch (IOException e) {
throw new ExceptionInInitializerError("Cannot load config", e);
}
}
}
Ключевые моменты
- Выполняется один раз при загрузке класса
- Выполняется ДО первого обращения к классу
- Выполняется ДО создания первого объекта
- Можно несколько static блоков — выполняются по порядку
- Используется для инициализации static переменных и ресурсов
- Нет доступа к instance переменным
- Исключения в static блоке приводят к ExceptionInInitializerError