← Назад к вопросам

Объекты каких стандартных классов являются immutable (неизменяемыми) в Java?

1.8 Middle🔥 131 комментариев
#SOLID и паттерны проектирования#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Immutable классы в Java

Что такое immutable (неизменяемость)

Immutable объект — это объект, который не может быть изменён после создания. Все его поля заполняются при создании и не могут быть изменены.

Стандартные immutable классы в Java

1. String

String str = "Hello";
str = str.concat(" World");  // создаёт НОВУЮ строку
// старая строка "Hello" остаётся неизменной

String s1 = "test";
String s2 = s1;
s2 = "changed";  // s1 остаётся "test"
System.out.println(s1);  // test

2. Обёртки примитивов

Integer num = 5;
num = 10;  // создаёт новый объект Integer

Double d = 3.14;
d = 2.71;  // новый объект Double

Boolean b = true;
// и т.д.

Все обёртки: Integer, Long, Double, Float, Byte, Short, Character, Boolean — неизменяемы.

3. BigInteger и BigDecimal

BigInteger num1 = new BigInteger("12345");
BigInteger num2 = num1.add(BigInteger.ONE);
// num1 остаётся "12345"
// num2 — это новый объект "12346"

BigDecimal price = new BigDecimal("19.99");
BigDecimal newPrice = price.multiply(new BigDecimal("2"));
// price не изменилась

4. Collections.unmodifiableXXX()

List<String> list = Arrays.asList("A", "B", "C");
List<String> immutableList = Collections.unmodifiableList(list);
immutableList.add("D");  // UnsupportedOperationException!

Map<String, Integer> map = new HashMap<>();
map.put("age", 25);
Map<String, Integer> immutableMap = Collections.unmodifiableMap(map);
immutableMap.put("name", 30);  // Exception

5. List.of(), Map.of(), Set.of() (Java 9+)

List<String> immutableList = List.of("A", "B", "C");
immutableList.add("D");  // UnsupportedOperationException

Map<String, Integer> immutableMap = Map.of("age", 25, "height", 180);
immutableMap.put("weight", 75);  // Exception

Set<Integer> immutableSet = Set.of(1, 2, 3, 4, 5);
immutableSet.add(6);  // Exception

6. java.time классы (LocalDate, LocalTime, ZonedDateTime)

LocalDate date = LocalDate.of(2025, 3, 23);
LocalDate nextDay = date.plusDays(1);
// date остаётся 2025-03-23
// nextDay — новый объект 2025-03-24

LocalTime time = LocalTime.of(15, 30, 0);
LocalTime laterTime = time.plusHours(2);
// time не изменилась

7. UUID

UUID id = UUID.randomUUID();
// UUID полностью immutable

8. Enum

public enum Status {
    ACTIVE, INACTIVE, PENDING
}
// Enum значения неизменяемы

Таблица стандартных immutable классов

КлассКатегорияПримечание
StringСтрокиСамый важный
Integer, Long, Double и т.д.ОбёрткиВсе обёртки примитивов
BigInteger, BigDecimalЧислаДля больших чисел
LocalDate, LocalTime, ZonedDateTimeДата/времяJava 8+
UUIDИдентификаторыВсегда immutable
EnumПеречисленияImmutable
Collections.unmodifiableList()КоллекцииДекоратор
List.of(), Map.of(), Set.of()Коллекции (Java 9+)Immutable

Почему String immutable?

// Безопасность: разные потоки могут использовать одну строку
String s1 = "test";
String s2 = s1;
// s1 и s2 указывают на один объект в памяти
// Так как String immutable, это безопасно

// Производительность: хеширование
Map<String, Integer> map = new HashMap<>();
map.put("key", 1);
// хеш строки не меняется, так как строка immutable

Как создать свой immutable класс

public final class Person {  // final запрещает наследование
    private final String name;    // final поле
    private final int age;        // final поле
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    // НЕТ setter методов!
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
}

Пример: StringBuilder vs String

// Медленно — создаёт много объектов String
String result = "";
for (int i = 0; i < 1000; i++) {
    result += "x";  // каждая операция создаёт новый String
}

// Быстро — используем mutable StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("x");
}
String result = sb.toString();

Преимущества immutable классов

Отличная безопасность в многопоточности — несколько потоков могут использовать один объект. Кеширование значений. Хеш объекта не меняется. Простота — нет нужды отслеживать изменения.

Вывод

Основные immutable классы: String (самый важный), обёртки примитивов (Integer, Long, Double и т.д.), BigInteger, BigDecimal, дата/время (LocalDate, LocalTime, ZonedDateTime), коллекции (Collections.unmodifiableXXX(), List.of(), Map.of(), Set.of()). Immutable классы предпочтительны для безопасности в многопоточности и предсказуемости поведения.