Массивы — это уникальные объекты в JVM, и понимание их структуры создано для лучшего кода.
Простейшим способом классификации типов данных в Java является их разделение на примитивы и объекты. К примитивам, как известно большинству разработчиков Java, относятся булевы числа, байты, символы, варианты целых чисел (short, int и long), а также варианты чисел с плавающей точкой (floats и doubles). Внутри JVM эти примитивы инстанцируются в сыром виде. Объявление переменной типа int создает в JVM 32-битное целое поле, с которым она может работать. Чаще всего эти примитивы создаются в стеке операндов, который строится при каждом вызове метода. (Заметным исключением являются статические примитивы, которые создаются в куче).
В отличие от простых выделенных примитивов, объекты — это сущности, которые окружают элемент данных методами, а иногда и дополнительными вспомогательными полями. Например, объект String содержит массив (мы вернемся к этому немного позже), в котором хранится содержимое строки, а также вспомогательные поля, которые используются различными методами, определенными для String. Объекты создаются в области памяти, называемой "куча", то есть они выделяются из свободной памяти.
Все объекты, за исключением массивов, имеют конструктор. Если в исходном коде не определен конструктор для нового объекта, Java-компилятор создает для него конструктор без параметров. Чаще всего этот конструктор вызывает конструктор по умолчанию в классе Object, который по факту ничего не делает.
Природа массивов
Массивы являются объектами. Однако внутри JVM массивы заметно отличаются от всех остальных объектов. Первое существенное отличие заключается в том, что массивы создаются JVM, а не явным или неявным вызовом функции new() руками разработчика. Когда компилятор Java впервые встречает набор скобок, прикрепленных к имени переменной, он выдает определенный бай-ткод, который указывает JVM на создание массива. Компилятор также указывает, какого типа элементы данных будет содержать массив (примитивы или объекты) и какова его размерность.
Далее JVM создает массив подходящего размера и типа и оборачивает его в виде объекта. То есть все методы, доступные в классе Object, которые наследуются, например, toString(), доступны и для массивов. Элементы последней размерности во вновь созданном массиве инициализируются значением по умолчанию для данного типа данных (нулевым значением для числовых типов, null для объектов).
Инициализация массивов
Как уже отмечалось, массивы не имеют конструкторов. Компилятор Java не создает конструктор по умолчанию, и разработчик не может указать конструктор. Одним из следствий является то, что массивы должны быть инициализированы явным образом до желаемых значений. Обычно это делается в цикле for или непосредственно в момент объявления массива, как показано в примере ниже: