← Назад к вопросам
Почему нельзя изменить размер массива?
1.6 Junior🔥 161 комментариев
#Коллекции#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему нельзя изменить размер массива в Java
Суть проблемы
В Java массивы имеют фиксированный размер, который задается при создании и не может быть изменен. Это фундаментальное проектное решение языка, основанное на том, как работает память.
1. Причина: выделение памяти в куче
Когда вы создаете массив, JVM выделяет непрерывный блок памяти в куче (heap) для хранения элементов:
int[] numbers = new int[5]; // Выделение памяти для 5 элементов
Физический адрес памяти:
Массив на адресе 0x1000:
0x1000: 0
0x1004: 0 (int = 4 байта)
0x1008: 0
0x100C: 0
0x1010: 0
2. Почему нельзя просто расширить
Нехватает места прямо после массива:
Массив numbers: [0][0][0][0][0] <- 0x1000 to 0x1013
Нельзя просто добавить сюда!
Там может быть другой объект
Другой объект: [A][B][C][D] <- 0x1014 to 0x1020
Если соседняя память занята, расширение невозможно. Пришлось бы перемещать весь соседний объект, что крайне дорого.
3. Производительность и предсказуемость
Фиксированный размер дает гарантии:
- O(1) доступ: arr[3] = мгновенный доступ к элементу
- Предсказуемость: нет скрытых аллокаций памяти
- Быстродействие: no resizing overhead
4. JVM не может гарантировать соседнюю память
JVM работает с кучей, где:
- Мусоркольектор (GC) перемещает объекты
- Фрагментация памяти неизбежна
- Нет гарантий соседней свободной памяти
5. Решение: используй Collection Framework
Для динамических размеров используй ArrayList:
// Неправильно: фиксированный размер
int[] numbers = new int[5];
numbers[5] = 100; // ArrayIndexOutOfBoundsException!
// Правильно: динамический размер
List<Integer> numbers = new ArrayList<>();
numbers.add(100); // OK
numbers.add(200); // OK
Как работает ArrayList (внутри) с расширением:
public class ArrayList<E> {
private Object[] elementData;
private int size = 0;
public void add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
}
private void ensureCapacity(int minCapacity) {
if (minCapacity > elementData.length) {
int newCapacity = elementData.length + (elementData.length >> 1);
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
}
Компромисс ArrayList
ArrayList платит цену:
- Расширение — это O(n) операция (копирование всех элементов)
- Больше памяти (часто несколько пустых слотов)
- Медленнее, чем обычный массив
Но это автоматическое и редкое событие (амортизированное O(1)).
Итог
- Массивы в Java — это низкоуровневая структура с фиксированным размером
- Причины: физическая организация памяти, производительность, простота
- Решение: используй ArrayList, LinkedList или другие Collections для динамических размеров
- Урок: понимай, когда нужен массив (performance-critical код) и когда нужна Collection