В Java массив является классом и расширяет Объект. Мне любопытно знать об этом специальном классе массива. Я не нахожу определение класса нигде. Выполнение getClass () .getName () дает странный результат.
String[] array = new String[]{"one","two"};
System.out.println(array.getClass().getName()); // prints [Ljava.lang.String;
Я хочу понять, как массив работает под капотом. Определение класса массива hardcoded в JVM?
Любые ресурсы, книги, ссылки на это будут полезны.
Спасибо.
Да, в основном массивы - это то, о чем виртуальная машина хорошо знает, как и примитивные типы. Существуют специальные инструкции байт-кода для работы с массивами - их создания, индексации в них и т. Д.
Что касается ресурсов для получения дополнительной информации - спецификация JVM , вероятно, является лучшей отправной точкой. В разделе 7.9 есть несколько примеров байт-кода, работающего с массивами.
Спецификация виртуальной машины Java объясняет в разделе 4.2, что означают такие имена, как [Ljava.lang.String;
. См: 4.2 Внутренняя форма полностью квалифицированных имен классов и интерфейсов.
В данном случае [
означает, что это тип массива, а Lclassname;
указывает, что это массив ссылок на объекты типа classname.
Таким образом, Ljava.lang.String;
означает String[]
.
Да, в JVM есть синтетический Class
, представляющий массив каждого возможного типа (например, Integer[].class
). Также есть один для каждого примитивного типа (например, int[].class
). Я не думаю, что это что-то, что имеет определение, например, исходный файл, где-либо. Они ведут себя, как и ожидалось; например, Number[].class
присваивается из Integer[].class
.
У него нет ни специальных методов, если вы это имеете в виду, ни специального исходного файла. Я даже не думаю, что поле length
, которое есть у типов массивов, считается определенным в этом классе, хотя, признаюсь, я не проверял; оно специально выделено в VM.
JLS 10.8 определяет это.
Class.getName
четко определяет эти «фанковые» имена массивов:
Если этот объект класса представляет ссылочный тип, который не является типом массива, то двоичное имя класса будет возвращается, как указано в Спецификации языка Java, Второе издание.
Если этот объект класса представляет примитивный тип или void, то возвращаемое имя является
String
, равным ключевому слову языка Java, соответствующему примитивному типу, илиvoid
.Если этот объект класса представляет класс массивов, то внутренняя форма имени состоит из имени типа элемента, которому предшествуют один или несколько
'['
символов, представляющих глубину вложенности массива. . Кодировка имен типов элементов следующая:Кодировка типов элементов логическое Z байт B символ C двойной D поплавок F int I длинный J короткий S класс или интерфейс Lclassname;
Все элементы типа массива следующие:
длина общедоступного конечного поля
, которое содержит количество компонентов массива (длина может быть положительной или нулевой)- Клон общедоступного метода
, который переопределяет метод с тем же именем в классе
Object
и не генерирует проверенных исключений- Все члены, унаследованные от
класса Object
; единственный методобъекта
, который не наследуется, - это егоклон
метод