Спецификация VM Формат файла класса


Содержание | Предыдущий | Следующий | ИндексСпецификация Виртуальной машины JavaTM


ГЛАВА 4

class Формат файла


Эта глава описывает виртуальную машину Java class формат файла. Каждый class файл содержит определение единого класса или интерфейса. Хотя у класса или интерфейса не должно быть внешнего представления, буквально содержавшегося в файле (например, потому что класс сгенерирован загрузчиком класса), мы будем в разговорной речи обращаться к любому допустимому представлению класса или взаимодействовать через интерфейс как являющийся в class формат файла.

A class файл состоит из потока 8-разрядных байтов. Все 16-разрядные, 32-разрядные, и 64-разрядные количества создаются, читая в два, четыре, и восемь последовательных 8-разрядных байтов, соответственно. Многобайтовые элементы данных всегда сохранены в порядке с обратным порядком байтов, где высокие байты на первом месте. В Java и Java 2 платформы, этот формат поддерживается интерфейсами java.io.DataInput и java.io.DataOutput и классы такой как java.io.DataInputStream и java.io.DataOutputStream.

Эта глава определяет свой собственный набор представления типов данных class данные файла: типы u1, u2, и u4 представьте без знака - два - или четырехбайтовое количество, соответственно. В Java и Java 2 платформы, эти типы могут быть считаны методами такой как readUnsignedByte, readUnsignedShort, и readInt из интерфейса java.io.DataInput.

Эта глава представляет class формат файла используя псевдоструктуры, записанные в нотации структуры подобной C. Избегать беспорядка с полями классов и экземпляров класса, и т.д., содержания структур, описывающих class формат файла упоминается как элементы. Последовательные элементы сохранены в class зарегистрируйте последовательно, не дополняя или выравнивание.

Таблицы, состоя из нуля или большего количества элементов переменного размера, используются в нескольких class файловые структуры. Хотя мы используем синтаксис массива подобный C, чтобы обратиться к табличным элементам, факт, что таблицы являются потоками структур переменного размера, означает, что не возможно преобразовать табличный индекс непосредственно в байтовое смещение в таблицу.

Где мы именуем структуру данных как массив, это состоит из нуля или более непрерывный фиксированный - измеренные элементы и может быть индексировано как массив.


4.1 ClassFile Структура

A class файл состоит из сингла ClassFile структура:


    ClassFile {      u4 magic;      u2 minor_version;      u2 major_version;      u2 constant_pool_count;      cp_info constant_pool[constant_pool_count-1];      u2 access_flags;      u2 this_class;      u2 super_class;      u2 interfaces_count;      u2 interfaces[interfaces_count];      u2 fields_count;      field_info fields[fields_count];      u2 methods_count;      method_info methods[methods_count];      u2 attributes_count;      attribute_info attributes[attributes_count];     }
Элементы в ClassFile структура следующие:

magic
magic элемент предоставляет магическое число, идентифицирующее class формат файла; у этого есть значение 0xCAFEBABE.

minor_version, major_version
Значения minor_version и major_version элементы являются номерами вспомогательной версии и номерами основной версии этого class файл. Вместе, майор и номер вспомогательной версии определяют версию class формат файла. Если a class у файла есть номер основной версии М. и номер вспомогательной версии м., мы обозначаем версию class формат файла как M.m. Таким образом, class версии формата файла могут быть упорядочены лексикографически, например, 1.5< 2.0 < 2.1.

, реализация виртуальной машины Java может поддерживать a class формат файла версии v, если и только если v находится в некотором непрерывном Ми 0 диапазона v Mj.m. Только Sun может определить, какой диапазон версий реализация виртуальной машины Java, соответствующая определенному уровню выпуска платформы Java, может поддерживать 1

constant_pool_count
Значение constant_pool_count элемент равен числу записей в constant_pool таблица плюс один. A constant_pool индекс считают допустимым, если это больше чем нуль и меньше чем constant_pool_count, с исключением для констант типа long и double отмеченный в §4.4.5.

constant_pool[]
constant_pool таблица структур (§4.4) представление различных строковых констант, класса и интерфейсных имен, имен полей, и других констант, которые упоминаются в пределах ClassFile структура и ее подструктуры. Формат каждого constant_pool запись таблицы обозначается ее первым байтом "тега".

constant_pool таблица индексируется от 1 к constant_pool_count-1.

access_flags
Значение access_flags элемент является маской флагов, используемых, чтобы обозначить права доступа к и свойства этого класса или интерфейса. Интерпретация каждого флага, когда установлено, находится как показано в Таблице 4.1.

Имя флага Значение Интерпретация
ACC_PUBLIC 0x0001 Объявленный public; может быть получен доступ снаружи его пакета.
ACC_FINAL 0x0010 Объявленный final; никакие подклассы не позволяются.
ACC_SUPER 0x0020 Методы суперкласса обработки особенно когда вызвано invokespecial инструкцией.
ACC_INTERFACE 0x0200 Интерфейс, не класс.
ACC_ABSTRACT 0x0400 Объявленный abstract;, возможно, не инстанцируется.


Интерфейс отличает ACC_INTERFACE устанавливаемый флаг. Если ACC_INTERFACE флаг не устанавливается, это class файл определяет класс, не интерфейс.

Если ACC_INTERFACE флаг этого class файл устанавливается, ACC_ABSTRACT флаг должен также быть установлен (§2.13.1) и ACC_PUBLIC флаг может быть установлен. Такой class у файла, возможно, нет ни одного из других флагов в Табличном 4.1 наборе.

Если ACC_INTERFACE флаг этого class файл не устанавливается, у него может быть любой из других флагов в Табличном 4.1 наборе. Однако, такой class у файла не может быть обоих ACC_FINAL и ACC_ABSTRACT набор флагов (§2.8.2).

Установка ACC_SUPER флаг указывает, какую из двух альтернативных семантик для ее invokespecial инструкции должна выразить виртуальная машина Java; ACC_SUPER флаг существует для обратной совместимости для кода, скомпилированного более старыми компиляторами Sun для языка программирования Java. Все новые реализации виртуальной машины Java должны реализовать семантику для invokespecial, задокументированного в эту спецификацию. Все новые компиляторы к набору команд виртуальной машины Java должны установить ACC_SUPER флаг. Сгенерированы более старые компиляторы Sun ClassFile флаги с ACC_SUPER сброс. Более старые реализации виртуальной машины Java Sun игнорируют флаг, если он устанавливается.

Все биты access_flags элемент, не присвоенный в Таблице 4.1, резервируется для будущего использования. Они должны быть обнулены в сгенерированном class файлы и должны быть проигнорированы реализациями виртуальной машины Java.

this_class
Значение this_class элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Class_info (§4.4.1) структура, представляющая класс или интерфейс, определяется этим class файл.

super_class
Для класса, значения super_class элемент или должен быть нулем или должен быть допустимым индексом в constant_pool таблица. Если значение super_class элемент является ненулевым, constant_pool запись по тому индексу должна быть a CONSTANT_Class_info (§4.4.1) структура, представляющая прямой суперкласс класса, определяется этим class файл. Ни прямой суперкласс, ни любой из его суперклассов не могут быть a final класс.

Если значение super_class элемент является нулем, тогда это class файл должен представить класс Object, единственный класс или интерфейс без прямого суперкласса.

Для интерфейса, значения super_class элемент должен всегда быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Class_info структура, представляющая класс Object.

interfaces_count
Значение interfaces_count элемент дает число прямых суперинтерфейсов этого класса или интерфейсного типа.

interfaces[]
Каждое значение в interfaces массив должен быть допустимым индексом в constant_pool таблица. constant_pool запись в каждом значении interfaces[я], где 0 я < interfaces_count, должен быть a CONSTANT_Class_info структура (§4.4.1), представляющая интерфейс, который является прямым суперинтерфейсом этого класса или интерфейсного типа, в слева направо порядок, данный в источнике для типа.

fields_count
Значение fields_count элемент дает число field_info структуры в fields таблица. field_info (§4.5) структуры представляют все поля, и переменные класса и переменные экземпляра, объявленные этим классом или интерфейсным типом.

fields[]
Каждое значение в fields таблица должна быть a field_info (§4.5) структура, дающая полное описание поля в этом классе или интерфейсе. fields таблица включает только те поля, которые объявляются этим классом или интерфейсом. Это не включает поля представления элементов, которые наследованы от суперклассов или суперинтерфейсов.

methods_count
Значение methods_count элемент дает число method_info структуры в methods таблица.

methods[]
Каждое значение в methods таблица должна быть a method_info (§4.6) структура, дающая полное описание метода в этом классе или интерфейсе. Если метод не native или abstract, инструкции виртуальной машины Java, реализовывая метод также предоставляются.

method_info структуры представляют все методы, объявленные этим классом или интерфейсным типом, включая методы экземпляра, класс (static) методы, методы инициализации экземпляра (§3.9), и любой класс или интерфейсный метод инициализации (§3.9). methods таблица не включает методы представления элементов, которые наследованы от суперклассов или суперинтерфейсов.

attributes_count
Значение attributes_count элемент дает число атрибутов (§4.7) в attributes таблица этого класса.

attributes[]
Каждое значение attributes таблица должна быть структурой атрибута (§4.7).

Единственные атрибуты, определенные этой спецификацией как появляющийся в attributes таблица a ClassFile структура SourceFile атрибут (§4.7.7) и Deprecated (§4.7.10) атрибут.

Реализация виртуальной машины Java обязана тихо игнорировать любые атрибуты в attributes таблица a ClassFile структура, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантику class файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).


4.2 Внутренняя Форма Полностью определенного Класса и Интерфейсных Имен

Класс и интерфейсные имена, которые появляются в class файловые структуры всегда представляются в полностью определенной форме (§2.7.5). Такие имена всегда представляются как CONSTANT_Utf8_info (§4.4.7) структуры и таким образом может быть оттянут, где не далее ограниченный, от всего набора символов Unicode. На имена классов и интерфейсы ссылаются оба от тех CONSTANT_NameAndType_info структуры (§4.4.6), у которых есть такие имена как часть их дескриптора (§4.3) и от всех CONSTANT_Class_info (§4.4.1) структуры.

По историческим причинам синтаксис полностью определенного класса и интерфейсных имен, которые появляются в class файловые структуры отличаются от знакомого синтаксиса полностью определенных имен, задокументированных в §2.7.5. В этой внутренней форме, периоды ASCII ('.') это обычно разделяет идентификаторы, которые составляют полностью определенное имя, заменяются наклонными чертами вправо ASCII ('/'). Например, нормальное полностью определенное имя класса Thread java.lang.Thread. В форме, используемой в дескрипторах в class формат файла, ссылка на имя класса Thread реализуется, используя a CONSTANT_Utf8_info структура, представляющая строку "java/lang/Thread".


4.3 Дескрипторы

Дескриптор является строкой, представляющей тип поля или метода. Дескрипторы представляются в class формат файла используя строки UTF-8 (§4.4.7) и таким образом может быть оттянут, где не далее ограниченный, от всего набора символов Unicode.

4.3.1 Нотация грамматики

Дескрипторы определяются, используя грамматику. Эта грамматика является рядом производства, которое описывает, как последовательности символов могут сформировать синтаксически корректные дескрипторы различных типов. Терминальные символы грамматики показывают полужирным шрифт фиксированной ширины. Нетерминальные символы показывают в курсиве. Определение нетерминального представляется именем нетерминального, определяемого, сопровождается двоеточием. Одна или более альтернативных правых сторон для нетерминального тогда следуют последующие строки. Например, производство:

FieldType:
     BaseType
     ObjectType
     ArrayType

состояния, что FieldType может представить или BaseType, ObjectType, или ArrayType.

Нетерминальный символ на правой стороне производства, которое сопровождается звездочкой (*), представляет нуль или более возможно различные значения, произведенные из который нетерминальный, добавленный без любого прошедшего пространства. Производство:

MethodDescriptor:
     (ParameterDescriptor*) ReturnDescriptor

состояния, что MethodDescriptor представляет левую круглую скобку, сопровождаемую нулем или большим количеством значений ParameterDescriptor, сопровождаемых правой круглой скобкой, сопровождаемой ReturnDescriptor.

4.3.2 Полевые Дескрипторы

Полевой дескриптор представляет тип класса, экземпляра, или локальной переменной. Это - серия символов, сгенерированных грамматикой:

    FieldDescriptor:

FieldType

    ComponentType:

FieldType

    FieldType:

BaseType

ObjectType

ArrayType

    BaseType:

B

C

D

F

Я

J

S

Z

    ObjectType:
L <имя класса>;

    ArrayType:
[ComponentType

Символы BaseType, L и; из ObjectType, и [ArrayType все символы ASCII. <Имя класса> представляет полностью определенный класс или интерфейсное имя. По историческим причинам это кодируется во внутренней форме (§4.2).

Интерпретация типов поля находится как показано в Таблице 4.2.

Символ BaseType Ввести Интерпретация
B byte байт со знаком
C char Символ Unicode
D double двойная точность значение с плавающей точкой
F float одинарная точность значение с плавающей точкой
Я int целое число
J long длинное целое
L <имя класса>; reference экземпляр класса <classname>
S short со знаком короткий
Z boolean true или false
[ reference одна размерность массива


Например, дескриптор переменной экземпляра типа int просто я. Дескриптор переменной экземпляра типа Object Ljava/lang/Object;. Отметьте что внутренняя форма полностью определенного имени для класса Object используется. Дескриптор переменной экземпляра, которая является многомерным double массив,

    double d[][][];

    [[[D

4.3.3 Дескрипторы метода

Дескриптор метода представляет параметры, которые метод берет и значение, которое это возвращает:

MethodDescriptor:
    (ParameterDescriptor*) ReturnDescriptor

Дескриптор параметра представляет параметр, который передают методу:

ParameterDescriptor:
    FieldType

Дескриптор возврата представляет тип значения, возвращенного из метода. Это - серия символов, сгенерированных грамматикой:

ReturnDescriptor:
    FieldType
    V

Символ V указывает, что метод не возвращает значения (его тип возврата void).

Дескриптор метода допустим, только если он представляет параметры метода с полной длиной 255 или меньше, где та длина включает содействие для this в случае экземпляра или интерфейсных вызовов метода. Полная длина вычисляется, суммируя вклады отдельных параметров, где параметр типа long или double вносит два модуля длине, и параметр любого другого типа вносит один модуль.

Например, дескриптор метода для метода

    Object mymethod(int i, double d, Thread t)

    (IDLjava/lang/Thread;)Ljava/lang/Object;
Отметьте что внутренние формы полностью определенных имен Thread и Object используются в дескрипторе метода.

Дескриптор метода для mymethod то же самое ли mymethod класс или метод экземпляра. Хотя метод экземпляра передают this, ссылка на текущий экземпляр класса, в дополнение к его намеченным параметрам, тот факт не отражается в дескрипторе метода. (Ссылка на this не передается к методу класса.) Ссылка на this передается неявно инструкциями вызова метода виртуальной машины Java, используемой, чтобы вызвать методы экземпляра.


4.4 Постоянный Пул

Инструкции виртуальной машины Java не полагаются на расположение времени выполнения классов, интерфейсов, экземпляров класса, или массивов. Вместо этого инструкции обращаются к символьной информации в constant_pool таблица.

Все constant_pool у записей таблицы есть следующий общий формат:


    cp_info {      u1 tag;      u1 info[];     }
Каждый элемент в constant_pool таблица должна начаться с 1-байтового тега, указывающего отчасти cp_info запись. Содержание info массив меняется в зависимости от значения tag. Допустимые теги и их значения перечисляются в Таблице 4.3. Каждый байт тега должен сопровождаться на два или больше байта, дающие информацию об определенной константе. Формат дополнительной информации меняется в зависимости от значения тега.

Постоянный Тип Значение
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1


4.4.1 CONSTANT_Class_info Структура

CONSTANT_Class_info структура используется, чтобы представить класс или интерфейс:


    CONSTANT_Class_info {      u1 tag;      u2 name_index;     }
Элементы CONSTANT_Class_info структура является следующим:

tag
tag у элемента есть значение CONSTANT_Class (7).

name_index
Значение name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая допустимый полностью определенный класс или интерфейсное имя (§2.8.1) закодированный во внутренней форме (§4.2).

Поскольку массивы являются объектами, коды операций anewarray и multianewarray могут сослаться на массив "классы" через CONSTANT_Class_info (§4.4.1) структуры в constant_pool таблица. Для таких классов массива имя класса является дескриптором типа массива. Например, имя класса, представляющее двумерное int тип массива

    int[][] 

    [[I
Имя класса, представляющее массив типа класса Thread

    Thread[] 

    [Ljava/lang/Thread;
Дескриптор типа массива допустим, только если он представляет 255 или меньше размерностей.

4.4.2 CONSTANT_Fieldref_info, CONSTANT_Methodref_info, и CONSTANT_InterfaceMethodref_info Структуры

Поля, методы, и интерфейсные методы представляются подобными структурами:


    CONSTANT_Fieldref_info {      u1 tag;      u2 class_index;      u2 name_and_type_index;     }

    CONSTANT_Methodref_info {      u1 tag;      u2 class_index;      u2 name_and_type_index;     }

    CONSTANT_InterfaceMethodref_info {      u1 tag;      u2 class_index;      u2 name_and_type_index;     }
Элементы этих структур следующие:

tag
tag элемент a CONSTANT_Fieldref_info у структуры есть значение CONSTANT_Fieldref (9).

tag элемент a CONSTANT_Methodref_info у структуры есть значение CONSTANT_Methodref (10).

tag элемент a CONSTANT_InterfaceMethodref_info у структуры есть значение CONSTANT_InterfaceMethodref (11).

class_index
Значение class_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Class_info структура (§4.4.1), представляющая класс или интерфейсный тип, который содержит объявление поля или метода.

class_index элемент a CONSTANT_Methodref_info структура должна быть типом класса, не интерфейсным типом. class_index элемент a CONSTANT_InterfaceMethodref_info структура должна быть интерфейсным типом. class_index элемент a CONSTANT_Fieldref_info структура может быть или типом класса или интерфейсным типом.

name_and_type_index
Значение name_and_type_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_NameAndType_info (§4.4.6) структура. Это constant_pool запись указывает на имя и дескриптор поля или метода. В a CONSTANT_Fieldref_info обозначенный дескриптор должен быть полевым дескриптором (§4.3.2). Иначе, обозначенный дескриптор должен быть дескриптором метода (§4.3.3).

Если имя метода a CONSTANT_Methodref_info структура начинается с a' <' ('\u003c'), тогда имя должно быть специальным именем <init>, представление метода инициализации экземпляра (§3.9). Такой метод не должен возвратить значение.

4.4.3 CONSTANT_String_info Структура

CONSTANT_String_info структура используется, чтобы представить постоянные объекты типа String:


    CONSTANT_String_info {      u1 tag;      u2 string_index;     }
Элементы CONSTANT_String_info структура следующие:

tag
tag элемент CONSTANT_String_info у структуры есть значение CONSTANT_String (8).

string_index
Значение string_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) тех, структура, представляющая последовательность символов, к который String объект состоит в том, чтобы быть инициализирован.

4.4.4 CONSTANT_Integer_info и CONSTANT_Float_info Структуры

CONSTANT_Integer_info и CONSTANT_Float_info структуры представляют числовые 4 байта (int и float) константы:


    CONSTANT_Integer_info {      u1 tag;      u4 bytes;     }

    CONSTANT_Float_info {      u1 tag;      u4 bytes;     }
Элементы этих структур следующие:

tag
tag элемент CONSTANT_Integer_info у структуры есть значение CONSTANT_Integer (3).

tag элемент CONSTANT_Float_info у структуры есть значение CONSTANT_Float (4).

bytes
bytes элемент CONSTANT_Integer_info структура представляет значение int постоянный. Байты значения сохранены в обратном порядке байтов (высокий байт сначала) порядок.

bytes элемент CONSTANT_Float_info структура представляет значение float постоянный в IEEE 754 единственный формат с плавающей точкой (§3.3.2). Байты единственного представления формата сохранены в обратном порядке байтов (высокий байт сначала) порядок.

Значение, представленное CONSTANT_Float_info структура определяется следующим образом. Байты значения сначала преобразовываются в int постоянные биты. Затем:

    	int s = ((bits >> 31) == 0) ? 1 : -1;
    	int e = ((bits >> 23) & 0xff);
    	int m = (e == 0) ?
    			(bits & 0x7fffff) << 1 :
    			(bits & 0x7fffff) | 0x800000;

Then the float value equals the result of the mathematical expression s·m·2e-150.

4.4.5 CONSTANT_Long_info и CONSTANT_Double_info Структуры

CONSTANT_Long_info и CONSTANT_Double_info представьте числовых 8 байтов (long и double) константы:


    CONSTANT_Long_info {      u1 tag;      u4 high_bytes;      u4 low_bytes;     }

    CONSTANT_Double_info {      u1 tag;      u4 high_bytes;      u4 low_bytes;     }
Все 8-байтовые константы приводят две записи в рабочее состояние в constant_pool таблица class файл. Если a CONSTANT_Long_info или CONSTANT_Double_info структура является элементом в constant_pool таблица по индексу n, тогда следующий применимый элемент в пуле располагается по индексу n+2. constant_pool индекс n+1 должно быть допустимым, но считается неприменимым 2

Элементы этих структур следующие:

tag
tag элемент CONSTANT_Long_info у структуры есть значение CONSTANT_Long (5).

tag элемент CONSTANT_Double_info у структуры есть значение CONSTANT_Double (6).

high_bytes, low_bytes
Без знака high_bytes и low_bytes элементы CONSTANT_Long_info структура вместе представляет значение long постоянный ((long) high_bytes << 32) + low_bytes, где байты каждого из high_bytes и low_bytes сохранены в обратном порядке байтов (высокий байт сначала) порядок.

high_bytes и low_bytes элементы CONSTANT_Double_info структура вместе представляет double значение в IEEE 754 двойной формат с плавающей точкой (§3.3.2). Байты каждого элемента сохранены в обратном порядке байтов (высокий байт сначала) порядок.

Значение, представленное CONSTANT_Double_info структура определяется следующим образом. high_bytes и low_bytes элементы сначала преобразовываются в long постоянные биты, который равен ((long) high_bytes << 32) + low_bytes. Затем:

  • Если биты 0x7ff0000000000000L, double значение будет положительной бесконечностью.
  • Если биты 0xfff0000000000000L, double значение будет отрицательной бесконечностью.
  • Если биты находятся в диапазоне 0x7ff0000000000001L через 0x7fffffffffffffffL или в диапазоне 0xfff0000000000001L через 0xffffffffffffffffL, double значением будет НЭН.
  • Во всех других случаях позволить s, e, и m будьте тремя значениями, которые могли бы быть вычислены из битов:
    	int s = ((bits >> 63) == 0) ? 1 : -1;
    	int e = (int)((bits >> 52) & 0x7ffL);
    	long m = (e == 0) ?
    		(bits & 0xfffffffffffffL) << 1 :
    		(bits & 0xfffffffffffffL) | 0x10000000000000L;
    Затем значение с плавающей точкой равняется double значение математического выражения s·m·2e-1075.

4.4.6 CONSTANT_NameAndType_info Структура

CONSTANT_NameAndType_info структура используется, чтобы представить поле или метод, не указывая, какому классу или интерфейсному типу это принадлежит:


    CONSTANT_NameAndType_info {      u1 tag;      u2 name_index;      u2 descriptor_index;     }
Элементы CONSTANT_NameAndType_info структура следующие:

tag
tag элемент CONSTANT_NameAndType_info у структуры есть значение CONSTANT_NameAndType (12).

name_index
Значение name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая или допустимое поле или имя метода (§2.7) сохраненный как простое имя (§2.7.1), то есть, как идентификатор языка программирования Java (§2.2) или как специальное имя метода <init> (§3.9).

descriptor_index
Значение descriptor_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая допустимый полевой дескриптор (§4.3.2) или дескриптор метода (§4.3.3).

4.4.7 CONSTANT_Utf8_info Структура

CONSTANT_Utf8_info структура используется, чтобы представить постоянные строковые значения.

Строки UTF-8 кодируются так, чтобы символьные последовательности, которые содержат только ненулевые символы ASCII, могли быть представлены, используя только 1 байт за символ, но символы до 16 битов могут быть представлены. Все символы в диапазоне '\u0001' к '\u007F' представляются единственным байтом:

0 биты 6-0

7 битов данных в байте дают значение представленного символа. Нулевой символ ('\u0000') и символы в диапазоне '\u0080' к '\u07FF' представляются парой байтов x и y:

x:
1 1 0 биты 10-6

y:
1 0 биты 5-0

Байты представляют символ со значением ((x & 0x1f) << 6) + (y & 0x3f).

Символы в диапазоне '\u0800' к '\uFFFF' представляются на 3 байта x, y, и z:

x:
1 1 1 0 биты 15-12

y:
1 0 биты 11-6

z:
1 0 биты 5-0

Символ со значением ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) представляется байтами.

Байты многобайтовых символов сохранены в class файл в обратном порядке байтов (высокий байт сначала) порядок.

Есть два различия между этим форматом и "стандартным" форматом UTF-8. Во-первых, нулевой байт (byte)0 кодируется, используя 2-байтовый формат, а не 1-байтовый формат, так, чтобы виртуальная машина Java, которую никогда не встраивали строки UTF-8, обнулила. Во-вторых, только 1 байт, 2 байта, и 3-байтовые форматы используются. Виртуальная машина Java не распознает дольше форматы UTF-8.

Для получения дополнительной информации относительно формата UTF-8, см. Файловую систему Безопасный Формат Преобразования UCS (FSS_UTF), X/Open Предварительная Спецификация (X/Open Company Ltd., Номер документа: P316). Эта информация также появляется в ISO/IEC 10646, Приложении P.

CONSTANT_Utf8_info структура


    CONSTANT_Utf8_info {      u1 tag;      u2 length;      u1 bytes[length];     }
Элементы CONSTANT_Utf8_info структура является следующим:

tag
tag элемент CONSTANT_Utf8_info у структуры есть значение CONSTANT_Utf8 (1).

length
Значение length элемент подает число байтов bytes массив (не длина получающейся строки). Строки в CONSTANT_Utf8_info структура не завершается нулем.

bytes[]
bytes массив содержит байты строки. Ни у какого байта не может быть значения (byte)0 или находитесь в диапазоне (byte)0xf0-(byte)0xff.


4.5 Поля

Каждое поле описывается a field_info структура. Никакие два поля в одном class у файла могут быть то же самое имя и дескриптор (§4.3.2). Формат этой структуры


    field_info {      u2 access_flags;      u2 name_index;      u2 descriptor_index;      u2 attributes_count;      attribute_info attributes[attributes_count];     }
Элементы field_info структура следующие:

access_flags
Значение access_flags элемент является маской флагов, используемых, чтобы обозначить право доступа к и свойства этого поля. Интерпретация каждого флага, когда установлено, находится как показано в Таблице 4.4.

Поля классов могут установить любой из флагов в Таблице 4.4. Однако, у определенного поля класса может быть самое большее один из ACC_PRIVATE, ACC_PROTECTED, и ACC_PUBLIC у набора флагов (§2.7.4) и, возможно, нет обоих ACC_FINAL и ACC_VOLATILE набор флагов (§2.9.1).

Имя флага Значение Интерпретация
ACC_PUBLIC 0x0001 Объявленный public; может быть получен доступ снаружи его пакета.
ACC_PRIVATE 0x0002 Объявленный private; применимый только в пределах класса определения.
ACC_PROTECTED 0x0004 Объявленный protected; может быть получен доступ в пределах подклассов.
ACC_STATIC 0x0008 Объявленный static.
ACC_FINAL 0x0010 Объявленный final; никакое дальнейшее присвоение после инициализации.
ACC_VOLATILE 0x0040 Объявленный volatile; не может кэшироваться.
ACC_TRANSIENT 0x0080 Объявленный transient; не записанный или читают персистентным диспетчером объектов.


Поля классов могут установить любой из флагов в Таблице 4.4. Однако, у определенного поля класса может быть самое большее один из ACC_PRIVATE, ACC_PROTECTED, и ACC_PUBLIC у набора флагов (§2.7.4) и, возможно, нет обоих ACC_FINAL и ACC_VOLATILE набор флагов (§2.9.1).

У всех полей интерфейсов должен быть их ACC_PUBLIC, ACC_STATIC, и ACC_FINAL у набора флагов и, возможно, нет ни одного из других флагов в Табличном 4.4 наборе (§2.13.3.1).

Все биты access_flags элемент, не присвоенный в Таблице 4.4, резервируется для будущего использования. Они должны быть обнулены в сгенерированном class файлы и должны быть проигнорированы реализациями виртуальной машины Java.

name_index
Значение name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info структура (§4.4.7), которая должна представить допустимое имя поля (§2.7) сохраненный как простое имя (§2.7.1), то есть, как идентификатор языка программирования Java (§2.2).

descriptor_index
Значение descriptor_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info структура (§4.4.7), которая должна представить допустимый полевой дескриптор (§4.3.2).

attributes_count
Значение attributes_count элемент указывает на число дополнительных атрибутов (§4.7) этого поля.

attributes[]
Каждое значение attributes таблица должна быть структурой атрибута (§4.7). У поля может быть любое число атрибутов, связанных с этим.

Атрибуты, определенные этой спецификацией как появляющийся в attributes таблица a field_info структура ConstantValue (§4.7.2), Synthetic (§4.7.6), и Deprecated (§4.7.10) атрибуты.

Реализация виртуальной машины Java должна распознать и правильно читать ConstantValue (§4.7.2) атрибуты, найденные в attributes таблица a field_info структура. Реализация виртуальной машины Java обязана тихо игнорировать любые другие атрибуты в attributes таблица, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантику class файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).


4.6 Методы

Каждый метод, включая каждый метод инициализации экземпляра (§3.9) и класс или интерфейсный метод инициализации (§3.9), описывается a method_info структура. Никакие два метода в одном class у файла могут быть то же самое имя и дескриптор (§4.3.3).

У структуры есть следующий формат:


    method_info {      u2 access_flags;      u2 name_index;      u2 descriptor_index;      u2 attributes_count;      attribute_info attributes[attributes_count];     }
Элементы method_info структура следующие:

access_flags
Значение access_flags элемент является маской флагов, используемых, чтобы обозначить право доступа к и свойства этого метода. Интерпретация каждого флага, когда установлено, находится как показано в Таблице 4.5.

Имя флага Значение Интерпретация
ACC_PUBLIC 0x0001 Объявленный public; может быть получен доступ снаружи его пакета.
ACC_PRIVATE 0x0002 Объявленный private; доступный только в пределах класса определения.
ACC_PROTECTED 0x0004 Объявленный protected; может быть получен доступ в пределах подклассов.
ACC_STATIC 0x0008 Объявленный static.
ACC_FINAL 0x0010 Объявленный final;, возможно, не переопределяется.
ACC_SYNCHRONIZED 0x0020 Объявленный synchronized; вызов обертывается в блокировку монитора.
ACC_NATIVE 0x0100 Объявленный native; реализованный на языке кроме Java.
ACC_ABSTRACT 0x0400 Объявленный abstract; никакая реализация не обеспечивается.
ACC_STRICT 0x0800 Объявленный strictfp; режим с плавающей точкой строг FP


Методы классов могут установить любой из флагов в Таблице 4.5. Однако, у определенного метода класса может быть самое большее один из ACC_PRIVATE, ACC_PROTECTED, и ACC_PUBLIC набор флагов (§2.7.4). Если у такого метода есть ACC_ABSTRACT отметьте устанавливает это, возможно, не имеет ни одного из ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC, ACC_STRICT, или ACC_SYNCHRONIZED набор флагов (§2.13.3.2).

У всех интерфейсных методов должен быть их ACC_ABSTRACT и ACC_PUBLIC у набора флагов и, возможно, нет ни одного из других флагов в Табличном 4.5 наборе (§2.13.3.2).

У определенного метода инициализации экземпляра (§3.9) может быть самое большее один из ACC_PRIVATE, ACC_PROTECTED, и ACC_PUBLIC у набора флагов и может также быть ACC_STRICT набор флага, но, возможно, не имеет ни одного из других флагов в Табличном 4.5 наборе.

Класс и интерфейсные методы инициализации (§3.9) вызывает неявно виртуальная машина Java; значение их access_flags элемент игнорируется за исключением настроек ACC_STRICT флаг.

Все биты access_flags элемент, не присвоенный в Таблице 4.5, резервируется для будущего использования. Они должны быть обнулены в сгенерированном class файлы и должны быть проигнорированы реализациями виртуальной машины Java.

name_index
Значение name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая любые из специальных имен методов (§3.9), <init> или <clinit>, или допустимое имя метода в языке программирования Java (§2.7), сохраненный как простое имя (§2.7.1).

descriptor_index
Значение descriptor_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая допустимый дескриптор метода (§4.3.3).

attributes_count
Значение attributes_count элемент указывает на число дополнительных атрибутов (§4.7) этого метода.

attributes[]
Каждое значение attributes таблица должна быть структурой атрибута (§4.7). У метода может быть любое число дополнительных атрибутов, связанных с этим.

Единственные атрибуты, определенные этой спецификацией как появляющийся в attributes таблица a method_info структура Code (§4.7.3), Exceptions (§4.7.4), Synthetic (§4.7.6), и Deprecated (§4.7.10) атрибуты.

Реализация виртуальной машины Java должна распознать и правильно читать Code (§4.7.3) и Exceptions (§4.7.4) атрибуты, найденные в attributes таблица a method_info структура. Реализация виртуальной машины Java обязана тихо игнорировать любые другие атрибуты в attributes таблица a method_info структура, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантику class файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).


4.7 Атрибуты

Атрибуты используются в ClassFile (§4.1), field_info (§4.5), method_info (§4.6), и Code_attribute (§4.7.3) структуры class формат файла. У всех атрибутов есть следующий общий формат:


    attribute_info {      u2 attribute_name_index;      u4 attribute_length;      u1 info[attribute_length];     }
Для всех атрибутов, attribute_name_index должен быть допустимый 16-разрядный индекс без знака в постоянный пул класса. constant_pool запись в attribute_name_index должен быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая имя атрибута. Значение attribute_length элемент указывает на продолжительность последующей информации в байтах. Длина не включает начальные шесть байтов, которые содержат attribute_name_index и attribute_length элементы.

Определенные атрибуты предопределяются как часть class спецификация файла. Предопределенные атрибуты SourceFile (§4.7.7), ConstantValue (§4.7.2), Code (§4.7.3), Exceptions (§4.7.4), InnerClasses (§4.7.5), Synthetic (§4.7.6), LineNumberTable (§4.7.8), LocalVariableTable (§4.7.9), и Deprecated (§4.7.10) атрибуты. В пределах контекста их использования в этой спецификации, то есть, в attributes таблицы class резервируются файловые структуры, в которых они появляются, имена этих предопределенных атрибутов.

Из предопределенных атрибутов, Code, ConstantValue, и Exceptions атрибуты должны быть распознаны и правильно считаны a class средство чтения файлов для корректной интерпретации class файл реализацией виртуальной машины Java. InnerClasses и Synthetic атрибуты должны быть распознаны и правильно считаны a class средство чтения файлов, чтобы должным образом реализовать Java и Java 2 библиотеки классов платформы (§3.12). Использование остающихся предопределенных атрибутов является дополнительным; a class средство чтения файлов может использовать информацию, которую они содержат, или иначе должны тихо проигнорировать те атрибуты.

4.7.1 Определение и Именование Новых Атрибутов

Компиляторам разрешают определить и испустить class файлы, содержащие новые атрибуты в attributes таблицы class файловые структуры. Реализациям виртуальной машины Java разрешают распознать и использовать новые атрибуты, найденные в attributes таблицы class файловые структуры. Однако, любой атрибут, не определенный как часть этой спецификации виртуальной машины Java, не должен влиять на семантику класса или интерфейсных типов. Реализации виртуальной машины Java обязаны тихо игнорировать атрибуты, которые они не распознают.

Например, определение нового атрибута, чтобы поддерживать специфичную для поставщика отладку разрешается. Поскольку реализации виртуальной машины Java обязаны игнорировать атрибуты, они не распознают, class файлы, предназначенные для той определенной реализации виртуальной машины Java, будут применимы другими реализациями, даже если те реализации не могут использовать дополнительную отладочную информацию что class файлы содержат.

Реализациям виртуальной машины Java определенно мешают выдать исключение или иначе отказаться использовать class файлы просто из-за присутствия некоторого нового атрибута. Конечно, инструменты, работающие на class файлы, возможно, не работают правильно если дано class файлы, которые не содержат все атрибуты, которых они требуют.

Два атрибута, которые предназначаются, чтобы быть отличными, но которые, оказывается, используют то же самое название атрибута и являются той же самой длины, будут конфликтовать на реализациях, которые распознают любой атрибут. У атрибутов, определенных кроме Sun, должны быть имена, выбранные согласно соглашению о присвоении имен пакета, определенному Спецификацией языка JavaTM. Например, у нового атрибута, определенного Netscape, могло бы быть имя "com.Netscape.new-attribute".3

Sun может определить дополнительные атрибуты в будущих версиях этого class спецификация файла.

4.7.2 ConstantValue Атрибут

ConstantValue атрибут является атрибутом фиксированной длины, используемым в attributes таблица field_info (§4.5) структуры. A ConstantValue атрибут представляет значение постоянного поля, которое должно быть (явно или неявно) static; то есть, ACC_STATIC бит (Таблица 4.4) в flags элемент field_info структура должна быть установлена. Может быть не больше, чем один ConstantValue атрибут в attributes таблица данного field_info структура. Постоянное поле, представленное field_info структура присваивается значение, на которое ссылается ConstantValue припишите как часть инициализации класса или интерфейса, объявляющего постоянное поле (§2.17.4). Это сразу происходит до вызова класса или интерфейсного метода инициализации (§3.9) того класса или интерфейса.

Если a field_info структура, представляющая не -static у поля есть a ConstantValue атрибут, тогда тот атрибут должен тихо быть проигнорирован. Каждая реализация виртуальной машины Java должна распознать ConstantValue атрибуты.

ConstantValue у атрибута есть следующий формат:


    ConstantValue_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 constantvalue_index;     }
Элементы ConstantValue_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "ConstantValue".

attribute_length
Значение attribute_length элемент a ConstantValue_attribute структура должна быть 2.

constantvalue_index
Значение constantvalue_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу дает постоянную величину, представленную этим атрибутом. constant_pool запись должна иметь тип, соответствующий полю, как показано Таблицей 4.6.

Тип поля Тип записи
long CONSTANT_Long
float CONSTANT_Float
double CONSTANT_Double
int, short, char, byte, boolean CONSTANT_Integer
String CONSTANT_String


4.7.3 Code Атрибут

Code атрибут является атрибутом переменной длины, используемым в attributes таблица method_info структуры. A Code атрибут содержит инструкции виртуальной машины Java и вспомогательную информацию для единственного метода, метод инициализации экземпляра (§3.9), или класс или интерфейсный метод инициализации (§3.9). Каждая реализация виртуальной машины Java должна распознать Code атрибуты. Если метод также native или abstract, method_info у структуры не должно быть a Code атрибут. Иначе, method_info структура должна иметь точно один Code атрибут.

Code у атрибута есть следующий формат:


    Code_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 max_stack;      u2 max_locals;      u4 code_length;      u1 code[code_length];      u2 exception_table_length;      { u2 start_pc;      u2 end_pc;      u2 handler_pc;      u2 catch_type;      } exception_table[exception_table_length];      u2 attributes_count;      attribute_info attributes[attributes_count];     }
Элементы Code_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "Code".

attribute_length
Значение attribute_length элемент указывает на длину атрибута, исключая начальные шесть байтов.

max_stack
Значение max_stack элемент дает максимальную глубину (§3.6.2) стека операнда этого метода в любой точке во время выполнения метода.

max_locals
Значение max_locals элемент дает число локальных переменных в массиве локальной переменной, выделенном на вызов этого метода, включая локальные переменные, используемые, чтобы передать параметры к методу на его вызове.

Самая большая локальная переменная индексирует для значения типа long или double max_locals-2. Самый большой индекс локальной переменной для значения любого другого типа max_locals-1.

code_length
Значение code_length элемент подает число байтов code массив для этого метода. Значение code_length должно быть больше чем нуль; code массив не должен быть пустым.

code[]
code массив дает фактические байты кода виртуальной машины Java, которые реализуют метод.

Когда code массив читается в память на адресуемой байтом машине, если первый байт массива будет выровненный на 4-байтовой границе, то tableswitch и lookupswitch 32-разрядные смещения составят выровненные 4 байта. (Сошлитесь на описания тех инструкций для получения дополнительной информации о последствиях code выравнивание массива.)

Подробные ограничения на содержание code массив обширен и дается в отдельном участке (§4.8).

exception_table_length
Значение exception_table_length элемент подает число записей exception_table таблица.

exception_table[]
Каждая запись в exception_table массив описывает один обработчик исключений в code массив. Порядок обработчиков в exception_table массив является существенным. См. Раздел 3.10 для большего количества деталей.

Каждый exception_table запись содержит следующие четыре элемента:

start_pc, end_pc
Значения этих двух элементов start_pc и end_pc укажите на диапазоны в code массив, в котором обработчик исключений является активным. Значение start_pc должен быть допустимый индекс в code массив кода операции инструкции. Значение end_pc любой должен быть допустимым индексом в code массив кода операции инструкции или должен быть равным code_length, длина code массив. Значение start_pc должны быть меньше чем значение end_pc.

start_pc является содержащим и end_pc является монопольным; то есть, обработчик исключений должен быть активным, в то время как счетчик программы в пределах интервала [start_pc, end_pc).4

handler_pc
Значение handler_pc элемент указывает на запуск обработчика исключений. Значение элемента должно быть допустимым индексом в code выстройте и должен быть индекс кода операции инструкции.

catch_type
Если значение catch_type элемент является ненулевым, это должен быть допустимый индекс в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Class_info структура (§4.4.1), представляющая класс исключений, что этот обработчик исключений определяется, чтобы поймать. Этот класс должен быть классом Throwable или один из его подклассов. Обработчик исключений вызовут, только если выданное исключение является экземпляром данного класса или одним из его подклассов.

Если значение catch_type элемент является нулем, этот обработчик исключений вызывают для всех исключений. Это используется, чтобы реализовать finally (см. Раздел 7.13, "Компилируя finally").

attributes_count
Значение attributes_count элемент указывает на число атрибутов Code атрибут.

attributes[]
Каждое значение attributes таблица должна быть структурой атрибута (§4.7). A Code у атрибута может быть любое число дополнительных атрибутов, связанных с этим.

В настоящий момент, LineNumberTable (§4.7.8) и LocalVariableTable (§4.7.9) атрибуты, оба из которых содержат отладочную информацию, определяются и используются с Code атрибут.

Реализации виртуальной машины Java разрешают тихо проигнорировать любые атрибуты в attributes таблица a Code атрибут. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантику class файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).

4.7.4 Exceptions Атрибут

Exceptions атрибут является атрибутом переменной длины, используемым в attributes таблица a method_info (§4.6) структура. Exceptions атрибут указывает, который проверял исключения, которые может выдать метод. Может быть самое большее один Exceptions атрибут в каждом method_info структура.

Exceptions у атрибута есть следующий формат:


    Exceptions_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 number_of_exceptions;      u2 exception_index_table[number_of_exceptions];     }
Элементы Exceptions_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "Exceptions".

attribute_length
Значение attribute_length элемент указывает на длину атрибута, исключая начальные шесть байтов.

number_of_exceptions
Значение number_of_exceptions элемент указывает на число записей в exception_index_table.

exception_index_table[]
Каждое значение в exception_index_table массив должен быть допустимым индексом в constant_pool таблица. constant_pool запись, на которую ссылается каждый табличный элемент, должна быть a CONSTANT_Class_info структура (§4.4.1), представляющая тип класса, который этот метод, как объявляют, бросает.

Метод должен выдать исключение, только если по крайней мере одному из следующих трех критериев соответствуют:

  • Исключение является экземпляром RuntimeException или один из его подклассов.

  • Исключение является экземпляром Error или один из его подклассов.

  • Исключение является экземпляром одного из классов исключений, определенных в exception_index_table только описанный, или один из их подклассов.
Эти требования не осуществляются в виртуальной машине Java; они осуществляются только во время компиляции.

4.7.5 InnerClasses Атрибут

InnerClasses attribute5 является атрибутом переменной длины в attributes таблица ClassFile (§4.1) структура. Если постоянный пул класса или интерфейса обращается к какому-либо классу, или взаимодействуйте через интерфейс, который не является элементом пакета, ClassFile структура должна иметь точно один InnerClasses атрибут в attributes таблица.

InnerClasses у атрибута есть следующий формат:


    InnerClasses_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 number_of_classes;      { u2 inner_class_info_index;      u2 outer_class_info_index;      u2 inner_name_index;      u2 inner_class_access_flags;      } classes[number_of_classes];     }
Элементы InnerClasses_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "InnerClasses".

attribute_length
Значение attribute_length элемент указывает на длину атрибута, исключая начальные шесть байтов.

number_of_classes
Значение number_of_classes элемент указывает на число записей в classes массив.

classes[]
Каждый CONSTANT_Class_info запись в constant_pool у таблицы, которая представляет класс или интерфейс C, который не является элементом пакета, должна быть точно одна соответствующая запись в classes массив.

Если у класса есть элементы, которые являются классами или интерфейсами, constant_pool таблица (и следовательно InnerClasses атрибут), должен обратиться к каждому такому элементу, даже если тот элемент иначе не упоминается классом. Эти правила подразумевают, что вложенный класс или интерфейсный элемент будут иметь InnerClasses информация для каждого класса включения и для каждого непосредственного элемента.

Каждый classes запись массива содержит следующие четыре элемента:

inner_class_info_index
Значение inner_class_info_index элемент должен быть нулем или допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Class_info (§4.4.1) структура, представляющая C. Остающиеся элементы в classes запись массива дает информацию о C.

outer_class_info_index
Если C не является элементом, значением outer_class_info_index элемент должен быть нулем. Иначе, значение outer_class_info_index элемент должен быть допустимым индексом в constant_pool таблица, и запись по тому индексу должны быть a CONSTANT_Class_info структура (§4.4.1), представляющая класс или интерфейсом которого C является элементом.

inner_name_index
Если C является анонимным, значение inner_name_index элемент должен быть нулем. Иначе, значение inner_name_index элемент должен быть допустимым индексом в constant_pool таблица, и запись по тому индексу должны быть a CONSTANT_Utf8_info структура (§4.4.7), которая представляет исходное простое имя C, как дано в исходном коде от который это class файл был скомпилирован.

inner_class_access_flags
Значение inner_class_access_flags элемент является маской флагов, используемых, чтобы обозначить права доступа к и свойства класса или соединить интерфейсом с C как объявлено в исходном коде от который это class файл был скомпилирован. Это используется компиляторами, чтобы восстановить исходную информацию, когда исходный код не доступен. Флаги показывают в Таблице 4.7.

Имя флага Значение Значение
ACC_PUBLIC 0x0001 Отмеченный или неявно public в источнике.
ACC_PRIVATE 0x0002 Отмеченный private в источнике.
ACC_PROTECTED 0x0004 Отмеченный protected в источнике.
ACC_STATIC 0x0008 Отмеченный или неявно static в источнике.
ACC_FINAL 0x0010 Отмеченный final в источнике.
ACC_INTERFACE 0x0200 Был interface в источнике.
ACC_ABSTRACT 0x0400 Отмеченный или неявно abstract в источнике.


Все биты inner_class_access_flags элемент, не присвоенный в Таблице 4.7, резервируется для будущего использования. Они должны быть обнулены в сгенерированном class файлы и должны быть проигнорированы реализациями виртуальной машины Java.

Виртуальная машина Java в настоящий момент не проверяет непротиворечивость InnerClasses атрибут с любым class на файл, фактически представляющий класс или интерфейс, ссылается атрибут.

4.7.6 Synthetic Атрибут

Synthetic attribute6 является атрибутом фиксированной длины в attributes таблица ClassFile (§4.1), field_info (§4.5), и method_info (§4.6) структуры. Элемент класса, который не появляется в исходном коде, должен быть отмечен, используя a Synthetic атрибут.

Synthetic у атрибута есть следующий формат:


    Synthetic_attribute {      u2 attribute_name_index;      u4 attribute_length;     }
Элементы Synthetic_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "Synthetic".

attribute_length
Значение attribute_length элемент является нулем.

4.7.7 SourceFile Атрибут

SourceFile атрибут является дополнительным атрибутом фиксированной длины в attributes таблица ClassFile (§4.1) структура. Может быть не больше, чем один SourceFile атрибут в attributes таблица данного ClassFile структура.

SourceFile у атрибута есть следующий формат:


    SourceFile_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 sourcefile_index;     }
Элементы SourceFile_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "SourceFile".

attribute_length
Значение attribute_length элемент a SourceFile_attribute структура должна быть 2.

sourcefile_index
Значение sourcefile_index элемент должен быть допустимым индексом в constant_pool таблица. Постоянная запись пула по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку.

Строка, на которую ссылаются sourcefile_index элемент будет интерпретироваться как указание на имя исходного файла от который это class файл был скомпилирован. Это не будет интерпретироваться как указание на имя каталога, содержащего файл или абсолютный путь для файла; такая специфичная для платформы дополнительная информация должна быть предоставлена интерпретатором времени выполнения или средством разработки в то время, когда имя файла фактически используется.

4.7.8 LineNumberTable Атрибут

LineNumberTable атрибут является дополнительным атрибутом переменной длины в attributes таблица a Code (§4.7.3) атрибут. Это может использоваться отладчиками, чтобы определить который часть виртуальной машины Java code массив соответствует данному номеру строки в файле первоисточника. Если LineNumberTable атрибуты присутствуют в attributes таблица данного Code атрибут, тогда они могут появиться в любом порядке. Кроме того, многократный LineNumberTable атрибуты могут вместе представить данную строку исходного файла; то есть, LineNumberTable атрибуты не должны быть непосредственными с исходными строками.

LineNumberTable у атрибута есть следующий формат:


    LineNumberTable_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 line_number_table_length;      { u2 start_pc;      u2 line_number;      } line_number_table[line_number_table_length];     }
Элементы LineNumberTable_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "LineNumberTable".

attribute_length
Значение attribute_length элемент указывает на длину атрибута, исключая начальные шесть байтов.

line_number_table_length
Значение line_number_table_length элемент указывает на число записей в line_number_table массив.

line_number_table[]
Каждая запись в line_number_table массив указывает, что номер строки в файле первоисточника изменяется в поданной точке code массив. Каждый line_number_table запись должна содержать следующие два элемента:

start_pc
Значение start_pc элемент должен указать на индекс в code массив, в котором начинается код для новой строки в файле первоисточника. Значение start_pc должны быть меньше чем значение code_length элемент Code атрибут которого это LineNumberTable атрибут.

line_number
Значение line_number элемент должен дать соответствующий номер строки в файле первоисточника.

4.7.9 LocalVariableTable Атрибут

LocalVariableTable атрибут является дополнительным атрибутом переменной длины a Code (§4.7.3) атрибут. Это может использоваться отладчиками, чтобы определить значение данной локальной переменной во время выполнения метода. Если LocalVariableTable атрибуты присутствуют в attributes таблица данного Code атрибут, тогда они могут появиться в любом порядке. Может быть не больше, чем один LocalVariableTable атрибут на локальную переменную в Code атрибут.

LocalVariableTable у атрибута есть следующий формат:


    LocalVariableTable_attribute {      u2 attribute_name_index;      u4 attribute_length;      u2 local_variable_table_length;      { u2 start_pc;      u2 length;      u2 name_index;      u2 descriptor_index;      u2 index;      } local_variable_table[local_variable_table_length];     }
Элементы LocalVariableTable_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "LocalVariableTable".

attribute_length
Значение attribute_length элемент указывает на длину атрибута, исключая начальные шесть байтов.

local_variable_table_length
Значение local_variable_table_length элемент указывает на число записей в local_variable_table массив.

local_variable_table[]
Каждая запись в local_variable_table массив указывает на диапазон code выстройте смещения, в пределах которых у локальной переменной есть значение. Это также указывает на индекс в массив локальной переменной текущего фрейма, в котором может быть найдена та локальная переменная. Каждая запись должна содержать следующие пять элементов:

start_pc, length
У данной локальной переменной должно быть значение в индексах в code массив в интервале [start_pc, start_pc+length], то есть, между start_pc и start_pc+length включительно. Значение start_pc должен быть допустимый индекс в code массив этого Code припишите и должен быть индекс кода операции инструкции. Любой значение start_pc+length должен быть допустимый индекс в code массив этого Code атрибут и быть индексом кода операции инструкции, или это должен быть первый индекс вне конца этого code массив.

name_index, descriptor_index
Значение name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна содержать a CONSTANT_Utf8_info (§4.4.7) структура, представляющая допустимое имя локальной переменной, сохраненное как простое имя (§2.7.1).

Значение descriptor_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна содержать a CONSTANT_Utf8_info (§4.4.7) структура, представляющая полевой дескриптор (§4.3.2) кодирование типа локальной переменной в исходной программе.

index
Данная локальная переменная должна быть в index в массиве локальной переменной текущего фрейма. Если локальная переменная в index имеет тип double или long, это занимает обоих index и index+1.

4.7.10 Deprecated Атрибут

Deprecated attribute7 является дополнительным атрибутом фиксированной длины в attributes таблица ClassFile (§4.1), field_info (§4.5), и method_info (§4.6) структуры. Класс, интерфейс, метод, или поле могут быть отмечены, используя a Deprecated атрибут, чтобы указать, что класс, интерфейс, метод, или поле были заменены. Интерпретатор времени выполнения или инструмент, который читает class формат файла, такой как компилятор, может использовать эту маркировку, чтобы советовать пользователю, что замененный класс, интерфейс, метод, или поле являются ссылкой. Присутствие a Deprecated атрибут не изменяет семантику класса или интерфейса.

Deprecated у атрибута есть следующий формат:


    Deprecated_attribute {      u2 attribute_name_index;      u4 attribute_length;     }
Элементы Deprecated_attribute структура следующие:

attribute_name_index
Значение attribute_name_index элемент должен быть допустимым индексом в constant_pool таблица. constant_pool запись по тому индексу должна быть a CONSTANT_Utf8_info (§4.4.7) структура, представляющая строку "Deprecated".

attribute_length
Значение attribute_length элемент является нулем.


4.8 Ограничения на Код виртуальной машины Java

Код виртуальной машины Java для метода, метод инициализации экземпляра (§3.9), или класс или интерфейсный метод инициализации (§3.9) сохранен в code массив Code атрибут a method_info структура a class файл. Этот раздел описывает ограничения, связанные с содержанием Code_attribute структура.

4.8.1 Статические Ограничения

Статические ограничения на a class файл - те, которые определяют отмеченность файла. За исключением статических ограничений на код виртуальной машины Java class файл, эти ограничения были даны в предыдущем разделе. Статические ограничения на виртуальную машину Java кодируют в a class файл определяет, как инструкции виртуальной машины Java должны быть размечены в code массив и каковы операнды отдельных инструкций должны быть.

Статические ограничения на инструкции в code массив следующие:

  • code массив не должен быть пустым, таким образом, code_length у элемента не может быть значения 0.

  • Значение code_length элемент должен быть меньше чем 65536.

  • Код операции первой инструкции в code массив начинается по индексу 0.

  • Только экземпляры инструкций, задокументированных в Раздел 6.4, могут появиться в code массив. Экземпляры инструкций, используя зарезервированные коды операций (§6.2) или любые коды операций, не задокументированные в эту спецификацию, возможно, не появляются в code массив.

  • Для каждой инструкции в code массив кроме последнего, индекс кода операции следующей инструкции равняется индексу кода операции текущей команды плюс длина той инструкции, включая все ее операнды. Широкая инструкция обрабатывается как любая другая инструкция в этих целях; код операции, определяющий работу, которую должна изменить широкая инструкция, обрабатывается как один из операндов той широкой инструкции. Тот код операции никогда не должен быть непосредственно достижимым вычислением.

  • Последний байт последней инструкции в code массив должен быть байтом по индексу code_length-1.
Статические ограничения на операнды инструкций в code массив следующие:

  • Цель каждой команды перехода и команды перехода (jsr, jsr_w, goto, goto_w, ifeq, ifne, ifle, iflt, ifge, ifgt, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmple, if_icmplt, if_icmpge, if_icmpgt, if_acmpeq, if_acmpne) должна быть кодом операции инструкции в пределах этого метода. Цель команды перехода или команды перехода никогда не должна быть кодом операции, используемым, чтобы определить работу, которая будет изменена широкой инструкцией; цель перехода или ответвления может быть широкой инструкцией непосредственно.

  • Каждая цель, включая значение по умолчанию, каждой tableswitch инструкции должна быть кодом операции инструкции в пределах этого метода. У каждой tableswitch инструкции должно быть много записей в ее таблице переходов, которая является непротиворечивой со значением ее табличных операндов низкого и прыжка в высоту, и ее низкая стоимость должна быть меньше чем или равной ее высокому значению. Никакая цель tableswitch инструкции не может быть кодом операции, используемым, чтобы определить работу, которая будет изменена широкой инструкцией; цель tableswitch может быть широкой инструкцией непосредственно.

  • Каждая цель, включая значение по умолчанию, каждой lookupswitch инструкции должна быть кодом операции инструкции в пределах этого метода. У каждой lookupswitch инструкции должно быть много смещенных соответствием пар, который является непротиворечивым со значением ее npairs операнда. Смещенные соответствием пары должны быть сортированы в увеличении числового порядка значением соответствия со знаком. Никакая цель lookupswitch инструкции не может быть кодом операции, используемым, чтобы определить работу, которая будет изменена широкой инструкцией; цель lookupswitch может быть широкой инструкцией непосредственно.

  • Операнд каждой ldc инструкции должен быть допустимым индексом в constant_pool таблица. Операнды каждой ldc_w инструкции должны представить допустимый индекс в constant_pool таблица. В обоих случаях постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Integer, CONSTANT_Float, или CONSTANT_String.

  • Операнды каждой ldc2_w инструкции должны представить допустимый индекс в constant_pool таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Long или CONSTANT_Double. Кроме того, последующий постоянный индекс пула должен также быть допустимым индексом в постоянный пул, и постоянная запись пула по тому индексу не должна использоваться.

  • Операнды каждого getfield, putfield, getstatic, и putstatic инструкция должны представить допустимый индекс в constant_pool таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Fieldref.

  • indexbyte операнды каждого invokevirtual, invokespecial, и invokestatic инструкция должны представить допустимый индекс в constant_pool таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Methodref.

  • Только invokespecial инструкции позволяют вызвать метод инициализации экземпляра (§3.9). Никакой другой метод, имя которого начинается с символа '<' ('\u003c') может быть вызван инструкциями вызова метода. В частности класс или интерфейсный метод инициализации особенно называют <clinit> никогда не вызывается явно от инструкций виртуальной машины Java, но только неявно виртуальной машиной Java непосредственно.

  • indexbyte операнды каждой invokeinterface инструкции должны представить допустимый индекс в constant_pool таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_InterfaceMethodref. Значение операнда количества каждой invokeinterface инструкции должно отразить число локальных переменных, необходимых, чтобы сохранить параметры, которые передадут к интерфейсному методу, как подразумевающийся дескриптором CONSTANT_NameAndType_info структура, на которую ссылаются CONSTANT_InterfaceMethodref постоянная запись пула. У четвертого байта операнда каждой invokeinterface инструкции должен быть нуль значения.

  • Операнды каждого instanceof, checkcast, новой, и anewarray инструкции и indexbyte операндов каждой multianewarray инструкции должны представить допустимый индекс в constant_pool таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Class.

  • Никакая anewarray инструкция не может использоваться, чтобы создать массив больше чем 255 размерностей.

  • Никакая новая инструкция не может сослаться на a CONSTANT_Class constant_pool запись таблицы, представляющая класс массива. Новая инструкция не может использоваться, чтобы создать массив. Новая инструкция также не может использоваться, чтобы создать экземпляр интерфейса или экземпляр abstract класс.

  • multianewarray инструкция должна использоваться только, чтобы создать массив типа, у которого есть, по крайней мере, так много размерностей как значение его операнда размерностей. Таким образом, в то время как multianewarray инструкция не обязана создавать все размерности типа массива, на который ссылаются его indexbyte операнды, это не должно попытаться создать больше размерностей, чем находятся в типе массива. Операнд размерностей каждой multianewarray инструкции не должен быть нулем.

  • atype операнд каждой newarray инструкции должен принять одно из значений T_BOOLEAN (4), T_CHAR (5), T_FLOAT (6), T_DOUBLE (7), T_BYTE (8), T_SHORT (9), T_INT (10), или T_LONG (11).

  • Индексный операнд каждого iload, fload, aload, istore, fstore, astore, iinc, и мочит инструкцию, должно быть неотрицательное целое число, не больше чем max_locals-1.

  • Неявный индекс каждого iload _ <n>, fload _ <n>, aload _ <n>, istore _ <n>, fstore _ <n>, и astore _ <n> инструкция должен быть не больше чем значение max_locals-1.

  • Индексный операнд каждого lload, dload, lstore, и dstore инструкция должны быть не больше чем значение max_locals-2.

  • Неявный индекс каждого lload _ <n>, dload _ <n>, lstore _ <n>, и dstore _ <n> инструкция должен быть не больше чем значение max_locals-2.

  • indexbyte операнды каждой широкой инструкции, изменяющей iload, fload, aload, istore, fstore, astore, мочат, или iinc инструкция должна представить неотрицательное целое число, не больше чем max_locals-1. indexbyte операнды каждой широкой инструкции, изменяющей lload, dload, lstore, или dstore инструкцию, должны представить неотрицательное целое число, не больше чем max_locals-2.

4.8.2 Структурные ограничения

Структурные ограничения на code массив определяет ограничения на отношения между инструкциями виртуальной машины Java. Структурные ограничения следующие:

  • Каждая инструкция должна только быть выполнена с соответствующим типом и числом параметров в стеке операнда и массиве локальной переменной, независимо от пути выполнения, который приводит к его вызову. Инструкция, работающая на значениях типа int также разрешается работать на значениях типа boolean, byte, char, и short. (Как отмечено в §3.3.4 и §3.11.1, виртуальная машина Java внутренне преобразовывает значения типов boolean, byte, char, и short вводить int.)

  • Если инструкция может быть выполнена вдоль нескольких различных путей выполнения, у стека операнда должна быть та же самая глубина (§3.6.2) до выполнения инструкции, независимо от взятого пути.

  • Ни в каком смысле во время выполнения не может порядок пары локальной переменной содержание значения типа long или double будьте инвертированы или разделенная пара. Ни в каком смысле не может локальные переменные такой пары управляться на индивидуально.

  • Никакая локальная переменная (или пара локальной переменной, в случае значения типа long или double) может быть получен доступ прежде, чем это будет присвоено значение.

  • Ни в каком смысле во время выполнения не может стек операнда становиться к глубине (§3.6.2) больше чем подразумеваемое max_stack элемент.

  • Ни в каком смысле во время выполнения не может больше значений быть вытолканным от стека операнда, чем это содержит.

  • Каждая invokespecial инструкция должна назвать метод инициализации экземпляра (§3.9), метод в текущем классе, или метод в суперклассе текущего класса.

  • Когда метод инициализации экземпляра (§3.9) вызывается, неинициализированный экземпляр класса должен быть в соответствующей позиции на стеке операнда. Метод инициализации экземпляра никогда не должен вызываться на инициализированный экземпляр класса.

  • Когда любой метод экземпляра вызывается или когда к любой переменной экземпляра получают доступ, экземпляр класса, который содержит метод экземпляра, или переменная экземпляра должна уже быть инициализирована.

  • Никогда не должно быть неинициализированного экземпляра класса на стеке операнда или в локальной переменной, когда любой назад переходит, берется. Никогда не должно быть неинициализированного экземпляра класса в локальной переменной в коде, защищенном обработчиком исключений. Однако, неинициализированный экземпляр класса может быть на стеке операнда в коде, защищенном обработчиком исключений. Когда исключение выдается, содержание стека операнда отбрасывается.

  • Каждый метод инициализации экземпляра (§3.9), за исключением метода инициализации экземпляра произошел от конструктора класса Object, должен вызвать любой другой метод инициализации экземпляра this или метод инициализации экземпляра ее прямого суперкласса super прежде, чем к его членам экземпляра получают доступ. Однако, поля экземпляра this это объявляется в текущем классе, может быть присвоен прежде, чем вызвать любой метод инициализации экземпляра.

  • Параметрами каждому вызову метода должен быть вызов метода, совместимый (§2.6.8) с дескриптором метода (§4.3.3).

  • Тип каждого экземпляра класса, который является целью инструкции вызова метода, должен быть присвоением, совместимым (§2.6.7) с классом или интерфейсным типом, определенным в инструкции.

  • Каждая инструкция возврата должна соответствовать тип возврата своего метода. Если метод возвращает a boolean, byte, char, short, или int, только ireturn инструкция может использоваться. Если метод возвращает a float, long, или double, только freturn, lreturn, или dreturn инструкция, соответственно, может использоваться. Если метод возвращает a reference введите, это должно сделать так использование areturn инструкции, и тип возвращенного значения должен быть присвоением, совместимым (§2.6.7) с дескриптором возврата (§4.3.3) метода. Все методы инициализации экземпляра, класс или интерфейсные методы инициализации, и методы, которые, как объявляют, возвратились void должен использовать только инструкцию возврата.

  • Если getfield или putfield привыкли к доступу a protected поле суперкласса, тогда тип получаемого доступ экземпляра класса должно быть тем же самым как или подкласс текущего класса. Если invokevirtual или invokespecial привыкли к доступу a protected метод суперкласса, тогда тип получаемого доступ экземпляра класса должен быть тем же самым как или подкласс текущего класса.

  • Тип каждого экземпляра класса, к которому получает доступ getfield инструкция или измененный putfield инструкцией, должен быть присвоением, совместимым (§2.6.7) с типом класса, определенным в инструкции.

  • Тип каждого значения, сохраненного putfield или putstatic инструкцией, должен быть совместимым с дескриптором поля (§4.3.2) экземпляра класса или класса, сохраненного в. Если тип дескриптора boolean, byte, char, short, или int, тогда значение должно быть int. Если тип дескриптора float, long, или double, тогда значение должно быть a float, long, или double, соответственно. Если тип дескриптора является a reference введите, тогда значение должно иметь тип, который является присвоением, совместимым (§2.6.7) с типом дескриптора.

  • Тип каждого значения сохранен в массив типа reference aastore инструкцией должно быть присвоение, совместимое (§2.6.7) с компонентным типом массива.

  • Каждая athrow инструкция должна бросить только значения, которые являются экземплярами класса Throwable или подклассов Throwable.

  • Выполнение никогда не уменьшается нижняя часть code массив.

  • Никакой обратный адрес (значение типа returnAddress) может быть загружен из локальной переменной.

  • Инструкция после каждого jsr или jsr_w инструкция могут быть возвращены к только синглом, мочат инструкцию.

  • Никакой jsr или jsr_w инструкция не могут использоваться, чтобы рекурсивно вызвать подпрограмму, если та подпрограмма уже присутствует в цепочке вызова подпрограммы. (Подпрограммы могут быть вложены при использовании try-finally конструкции изнутри a finally пункт. Для получения дополнительной информации по подпрограммам виртуальной машины Java см. §4.9.6.)

  • Каждый экземпляр типа returnAddress может быть возвращен к самое большее однажды. Если мочить инструкция возвращается к вопросу в цепочке вызова подпрограммы выше мочить инструкции, соответствующей приведенному примеру типа returnAddress, тогда тот экземпляр никогда не может использоваться в качестве обратного адреса.

4.9 Проверка class Файлы

Даже при том, что компилятор Sun для языка программирования Java пытается произвести только файлы класса, которые удовлетворяют все статические ограничения в предыдущих разделах, у виртуальной машины Java нет никакой гарантии, что любой файл, который просят загрузить, был сгенерирован тем компилятором или должным образом формируется. Приложения, такие как браузер всемирной паутины HotJava Sun не загружают исходный код, который они тогда компилируют; эти приложения уже скомпилированная загрузка class файлы. Браузер HotJava должен определить ли class файл был произведен защищенным компилятором или противником, пытающимся использовать виртуальную машину.

Дополнительной проблемой со временем компиляции, проверяя является скос версии. Пользователь, возможно, успешно скомпилировал класс, сказать PurchaseStockOptions, быть подклассом TradingClass. Но определение TradingClass возможно, изменился со времени класс был скомпилирован в пути, который не является совместимым с существующими ранее двоичными файлами. Методы, возможно, были удалены или имели свои типы возврата или измененные модификаторы. Поля, возможно, изменили типы или изменились от переменных экземпляра до переменных класса. Модификаторы доступа метода или переменной, возможно, изменились от public к private. Для обсуждения этих проблем см. Главу 13, "Совместимость на уровне двоичных кодов," в первом выпуске Спецификации языка JavaTM или эквивалентной главы во втором выпуске.

Из-за этих потенциальных проблем виртуальная машина Java должна проверить для себя, что требуемые ограничения удовлетворяются class файлы это пытается соединиться. Реализация виртуальной машины Java проверяет что каждый class файл удовлетворяет необходимые ограничения при соединении времени (§2.17.3). Структурные ограничения на код виртуальной машины Java могут быть проверены, используя простую программу автоматического доказательства теоремы.

Разовая соединением проверка улучшает производительность интерпретатора. Могут быть устранены дорогие проверки, которые должны были бы иначе быть выполнены, чтобы проверить ограничения во время выполнения для каждой интерпретируемой инструкции. Виртуальная машина Java может предположить, что эти проверки были уже выполнены. Например, виртуальная машина Java будет уже знать следующее:

  • Нет никаких переполнений стека операнда или потерь значимости.

  • Все использование локальной переменной и хранилища допустимы.

  • Параметры всем инструкциям виртуальной машины Java имеют допустимые типы.
Sun class верификатор файла независим от любого компилятора. Это должно сертифицировать весь код, сгенерированный компилятором Sun для языка программирования Java; это должно также сертифицировать код, который другие компиляторы могут генерировать, так же как код, который не мог возможно генерировать текущий компилятор. Любой class файл, который удовлетворяет структурные критерии и статические ограничения, будет сертифицирован верификатором.

class верификатор файла также независим от языка программирования Java. Программы, записанные на других языках, могут быть скомпилированы в class формат файла, но передаст проверку, только если весь одинаковый ограничения удовлетворяются.

4.9.1 Процесс Проверки

class верификатор файла работает в четырех передачах:

Передача 1:
Когда предполагаемое class файл загружается (§2.17.2) виртуальной машиной Java, виртуальная машина Java сначала гарантирует, что у файла есть основной формат a class файл. Первые четыре байта должны содержать правильное магическое число. Все распознанные атрибуты должны иметь надлежащую длину. class файл не должен быть усеченным или иметь дополнительные байты в конце. Постоянный пул не должен содержать поверхностно неузнаваемую информацию.

В то время как class проверка файла должным образом происходит во время класса, соединяющегося (§2.17.3), эта проверка на основной class целостность файла необходима для любой интерпретации class содержание файла и, как могут полагать, является логически частью процесса проверки.

Передача 2:
Когда class файл соединяется, верификатор выполняет всю дополнительную проверку, которая может быть сделана, не смотря на code массив Code атрибут (§4.7.3). Проверки, выполняемые этой передачей, включают следующее:

  • Обеспечение этого final классы не разделяются на подклассы и это final методы не переопределяются.

  • Проверка, что каждый класс (кроме Object) имеет прямой суперкласс.

  • Обеспечение, что постоянный пул удовлетворяет задокументированные статические ограничения: например, то, что каждый CONSTANT_Class_info структура в постоянном пуле содержит в name_index элемент допустимый постоянный индекс пула для a CONSTANT_Utf8_info структура.

  • Проверка, что у всех полевых ссылок и ссылок метода в постоянном пуле есть допустимые имена, допустимые классы, и допустимый дескриптор типа.
Отметьте, что, когда это смотрит на поле и ссылки метода, эта передача не проверяет, чтобы удостовериться, что данное поле или метод фактически существуют в данном классе, и при этом это не проверяет, что данные дескрипторы типа обращаются к реальным классам. Это проверяет только, что эти элементы хорошо формируются. Более подробная проверка задерживается до передач 3 и 4.

Передача 3:
Во время соединения верификатор проверяет code массив Code атрибут для каждого метода class файл, выполняя анализ потока данных каждого метода. Верификатор гарантирует, что в любой данной точке в программе, независимо от того какой путь выполнения кода берется, чтобы достигнуть той точки, следующее является истиной:

  • Стек операнда всегда является тем же самым размером и содержит те же самые типы значений.

  • Ни к какой локальной переменной не получают доступ, если это, как не известно, содержит значение соответствующего типа.

  • Методы вызываются с соответствующими параметрами.

  • Поля присваиваются, только используя значения соответствующих типов.

  • У всех кодов операций есть соответствующие параметры типа на стеке операнда и в массиве локальной переменной.
Для дополнительной информации об этой передаче см. Раздел 4.9.2, "Верификатор Байт-кода."

Передача 4:
По причинам эффективности задерживаются определенные тесты, которые могли в принципе быть выполнены в Передаче 3, до первого раза фактически вызывается код для метода. Таким образом, Передача 3 из верификатора избегает загружаться class файлы, если это не имеет к.

Например, если метод вызывает другой метод, который возвращает экземпляр класса A, и тот экземпляр присваивается только полю того же самого типа, верификатор не потрудился проверять если класс A фактически существует. Однако, если это присваивается полю типа B, определения обоих A и B должен быть загружен в гарантировать это A подкласс B.

Передача 4 является виртуальной передачей, проверка которой делается соответствующими инструкциями виртуальной машины Java. В первый раз инструкция, что ссылается на тип, выполняется, выполняющаяся инструкция делает следующее:

  • Загрузки в определении типа, на который ссылаются, если это не было уже загружено.

  • Проверки, что в настоящий момент выполняющемуся типу позволяют сослаться на тип.
В первый раз, когда инструкция вызывает метод, или доступы или изменяет поле, выполняющаяся инструкция делает следующее:

  • Гарантирует, что метод, на который ссылаются, или поле существуют в данном классе.

  • Проверки, что у метода, на который ссылаются, или поля есть обозначенный дескриптор.

  • Проверки, что у в настоящий момент выполняющегося метода есть доступ к методу, на который ссылаются, или полю.
Виртуальная машина Java не должна проверить тип объекта на стеке операнда. Та проверка была уже сделана Передачей 3. Ошибки, которые обнаруживаются в Передаче 4 экземпляра причины подклассов LinkageError быть брошенным.

Реализации виртуальной машины Java позволяют выполнить любую из Передачи 4 шага как часть Передачи 3; см. 2.17.1, "Запуск Виртуальной машины" для примера и большего количества обсуждения.

В одной из реализаций виртуальной машины Java Sun, после того, как была выполнена проверка, инструкция в коде виртуальной машины Java заменяется альтернативной формой инструкции. Эта альтернативная инструкция указывает, что проверка, необходимая этой инструкции, имела место и не должна быть выполнена снова. Последующие вызовы метода таким образом будут быстрее. Это недопустимо для этих альтернативных форм инструкции, чтобы появиться в class файлы, и с ними никогда не должен встречаться верификатор.

4.9.2 Верификатор Байт-кода

Как обозначено ранее, Передача 3 из процесса проверки является самой сложной из четырех передач class проверка файла. Этот раздел смотрит на проверку кода виртуальной машины Java в Передаче 3 более подробно.

Код для каждого метода проверяется независимо. Во-первых, байты, которые составляют код, разбиваются в последовательность инструкций, и индекс в code массив запуска каждой инструкции размещается в массив. Верификатор тогда проходит через код во второй раз и анализирует инструкции. Во время этой передачи структура данных создается, чтобы содержать информацию о каждой инструкции виртуальной машины Java в методе. Операнды, если таковые вообще имеются, каждой инструкции проверяются, чтобы удостовериться, что они допустимы. Например:

  • Ответвления должны быть в пределах границ code массив для метода.

  • Цели всех инструкций потока управления - каждый запуск инструкции. В случае широкой инструкции широкий код операции считают запуском инструкции, и кодом операции, дающим работу, измененную, которым широкая инструкция, как полагают, не запускает инструкцию. Ответвления в середину инструкции отвергаются.

  • Никакая инструкция не может получить доступ или изменить локальную переменную по индексу, больше чем или равный числу локальных переменных, что его метод указывает, что это выделяет.

  • Все ссылки на постоянный пул должны быть к записи соответствующего типа. Например: инструкция ldc может использоваться только для данных типа int или float или для экземпляров класса String; инструкция getfield должна сослаться на поле.

  • Код не заканчивается в середине инструкции.

  • Выполнение не может уменьшиться конец кода.

  • Для каждого обработчика исключений начальная и конечная точка кода, защищенного обработчиком, должна быть в начале инструкции или, в случае конечной точки, сразу мимо конца кода. Начальная точка должна быть перед конечной точкой. Код обработчика исключений должен запуститься в допустимой инструкции, и он, возможно, не запускается в коде операции, изменяемом широкой инструкцией.
Для каждой инструкции метода верификатор записывает содержание стека операнда и содержание массива локальной переменной до выполнения той инструкции. Для стека операнда это должно знать высоту стека и тип каждого значения на этом. Для каждой локальной переменной это должно знать или тип содержания той локальной переменной или что локальная переменная содержит неприменимое или неизвестное значение (это могло бы быть неинициализированным). Верификатор байт-кода не должен различить целочисленные типы (например, byte, short, char) когда определение значения вводит на стеке операнда.

Затем, поток данных анализатор инициализируется. Для первой инструкции метода локальные переменные, которые представляют параметры первоначально, содержат значения типов, обозначенных дескриптором типа метода; стек операнда пуст. Все другие локальные переменные содержат недопустимое значение. Для других инструкций, которые еще не были исследованы, никакая информация не доступна относительно стека операнда или локальных переменных.

Наконец, поток данных анализатор выполняется. Для каждой инструкции "измененный" бит указывает, нужно ли на эту инструкцию смотреть. Первоначально, "измененный" бит устанавливается только для первой инструкции. Поток данных анализатор выполняет следующий цикл:

  1. Выберите инструкцию виртуальной машины, "измененный" бит которой устанавливается. Если никакая инструкция не остается, чей "измененный" бит устанавливается, метод был успешно проверен. Иначе, выключите "измененный" бит выбранной инструкции.

  2. Смоделируйте эффект инструкции по стеку операнда и массиву локальной переменной, делая следующее:

    • Если значения использования инструкции от стека операнда, гарантируйте, что есть достаточное число значений на стеке и что главные значения на стеке имеют соответствующий тип. Иначе, сбои проверки.

    • Если инструкция использует локальную переменную, гарантируйте, что указанная локальная переменная содержит значение соответствующего типа. Иначе, сбои проверки.

    • Если значения нажатий инструкции на стек операнда, гарантируйте, что есть достаточная комната на стеке операнда для новых значений. Добавьте обозначенные типы к вершине смоделированного стека операнда.

    • Если инструкция изменяет локальную переменную, запишите это, локальная переменная теперь содержит новый тип.

  3. Определите инструкции, которые могут следовать за текущей командой. Инструкции преемника могут быть одним из следующего:

    • Следующая инструкция, если текущая команда не является безусловной инструкцией передачи управления (например goto, возврат, или athrow). Проверка перестала работать, если возможно "уменьшиться" последняя инструкция метода.

    • Цель (и) условного или безусловного перехода или переключателя.

    • Любые обработчики исключений для этой инструкции.

  4. Объедините состояние стека операнда и массива локальной переменной в конце выполнения текущей команды в каждую из инструкций преемника. В особом случае передачи управления в обработчик исключений стек операнда устанавливается содержать единственный объект типа исключения, обозначенного информацией об обработчике исключений.

    • Если это - первый раз, когда инструкцию преемника посетили, запишите это, стек операнда и значения локальной переменной, вычисленные в шагах 2 и 3, являются состоянием стека операнда и массива локальной переменной до выполнения инструкции преемника. Установите "измененный" бит для инструкции преемника.

    • Если инструкция преемника была замечена прежде, уже объедините стек операнда и значения локальной переменной, вычисленные в шагах 2 и 3 в значения там. Установите "измененный" бит, если есть какая-либо модификация к значениям.

  5. Продолжайте в шаге 1.
Чтобы объединить два стека операнда, число значений на каждом стеке должно быть идентичным. Типы значений на стеках должны также быть идентичными, за исключением того, что по-другому введенный reference значения могут появиться в соответствующих местах на двух стеках. В этом случае объединенный стек операнда содержит a reference к экземпляру первого общего суперкласса двух типов. Такой ссылочный тип всегда существует потому что тип Object суперкласс всего класса и интерфейсных типов. Если стеки операнда не могут быть объединены, проверка сбоев метода.

Чтобы объединить два состояния массива локальной переменной, соответствующие пары локальных переменных сравниваются. Если два типа не идентичны, то, если оба не содержат reference значения, записи верификатора, что локальная переменная содержит неприменимое значение. Если обе из пары локальных переменных содержат reference значения, объединенное состояние содержит a reference к экземпляру первого общего суперкласса двух типов.

Если поток данных, анализатор работает на методе, не сообщая об отказе проверки, то метод был успешно проверен Передачей 3 из class верификатор файла.

Определенные инструкции и типы данных усложняют поток данных анализатор. Мы теперь исследуем каждый из них более подробно.

4.9.3 Значения Типов long и double

Значения long и double типы обрабатываются особенно процессом проверки.

Всякий раз, когда значение типа long или double перемещается в локальную переменную по индексу n, индекс n + 1 особенно отмечается, чтобы указать, что это было зарезервировано значением по индексу n и, возможно, не используется в качестве индекса локальной переменной. Любое значение ранее по индексу n + 1 становится неприменимым.

Всякий раз, когда значение перемещается в локальную переменную по индексу n, индекс n - 1 исследуется, чтобы видеть, является ли это индекс значения типа long или double. Если так, локальная переменная по индексу n - 1 изменяется, чтобы указать, что это теперь содержит неприменимое значение. Начиная с локальной переменной по индексу n был перезаписан, локальная переменная по индексу n - 1 не может представить значение типа long или double.

Контакт со значениями типов long или double на операнде стек более прост; верификатор обрабатывает их как единственные значения на стеке. Например, код проверки для dadd кода операции (добавляют два double значения), проверяет, что лучшие два элемента на стеке имеют оба тип double. Когда вычисление операнда складывает длину, значения типа long и double имейте длину два.

Невведенные инструкции, которые управляют стеком операнда, должны обработать значения типа double и long как атомарный (неделимый). Например, верификатор сообщает об отказе, если главное значение на стеке является a double и это встречается с инструкцией те, которые выталкивают или копируют. Инструкции pop2 или dup2 должны использоваться вместо этого.

4.9.4 Методы Инициализации экземпляра и Недавно Создаваемые Объекты

Создание нового экземпляра класса является многошаговым процессом. Оператор


    ...     new myClass(i, j, k);     ...
может быть реализован следующим:


    ...     new #1 // Allocate uninitialized space for myClass     dup // Duplicate object on the operand stack     iload_1 // Push i     iload_2 // Push j     iload_3 // Push k     invokespecial #5 // Invoke myClass.<init>     ...
Эта последовательность инструкции листы недавно создаваемый и инициализированный объект сверху стека операнда. (Дополнительные примеры компиляции к набору команд виртуальной машины Java даются в Главе 7, "Компилирующей для виртуальной машины Java.")

Метод инициализации экземпляра (§3.9) для класса myClass рассматривает новый неинициализированный объект как this параметр в локальной переменной 0. Прежде, чем тот метод вызывает другой метод инициализации экземпляра myClass или его прямой суперкласс на this, единственная работа метод может выполнить на this присваивает поля, объявленные в пределах myClass.

Делая анализ потока данных методов экземпляра, верификатор инициализирует локальную переменную 0 содержать объект текущего класса, или, например методы инициализации, локальная переменная 0 содержит специальный тип, указывающий на неинициализированный объект. После того, как соответствующий метод инициализации экземпляра вызывается (от текущего класса или текущего суперкласса) на этом объекте, все возникновения этого специального типа на модели верификатора стека операнда и в массиве локальной переменной заменяются текущим типом класса. Верификатор отклоняет код, который использует новый объект прежде, чем это было инициализировано, или это инициализирует объект не раз. Кроме того, это гарантирует, что каждый нормальный возврат метода вызвал метод инициализации экземпляра или в классе этого метода или в прямом суперклассе.

Точно так же специальный тип создается и спешил модель верификатора стека операнда как результат новой инструкции виртуальной машины Java. Специальный тип указывает на инструкцию, которой экземпляр класса создавался и тип неинициализированного создаваемого экземпляра класса. Когда метод инициализации экземпляра вызывается на тот экземпляр класса, все возникновения специального типа заменяются намеченным типом экземпляра класса. Это изменение в типе может распространить к последующим инструкциям, поскольку анализ потока данных продолжается.

Число инструкции должно быть сохранено как часть специального типа, поскольку могут быть многократные еще инициализированные экземпляры существующего класса на стеке операнда когда-то. Например, последовательность инструкции виртуальной машины Java, которая реализует

new InputStream(new Foo(), new InputStream("foo"))

может иметь два неинициализированных экземпляра InputStream на операнде складывают сразу. Когда метод инициализации экземпляра вызывается на экземпляр класса, только те возникновения специального типа на стеке операнда или в массиве локальной переменной, которые являются тем же самым объектом, как экземпляр класса заменяется.

У допустимой последовательности инструкции не должно быть неинициализированного объекта на стеке операнда или в локальной переменной во время назад ответвление, или в локальной переменной в коде, защищенном обработчиком исключений или a finally пункт. Иначе, окольная часть кода могла бы дурачить верификатор, заставляя думать, это инициализировало экземпляр класса, когда это, фактически, инициализировало экземпляр класса, создаваемый в предыдущей передаче через цикл.

4.9.5 Обработчики исключений

Код виртуальной машины Java, произведенный компилятором Sun для языка программирования Java всегда, генерирует обработчики исключений так, что:

  • Или диапазоны инструкций, защищенных двумя различными обработчиками исключений всегда, являются абсолютно непересекающимися, или иначе каждый - поддиапазон другого. Никогда нет частичного перекрытия диапазонов.

  • Обработчик для исключения никогда не будет в коде, который защищается.

  • Единственная запись в обработчик исключений через исключение. Невозможно провалиться или "goto" обработчик исключений.
Эти ограничения не осуществляются class верификатор файла, так как они не ставят под угрозу целостность виртуальной машины Java. Пока каждый неисключительный путь к причинам обработчика исключений там, чтобы быть единственным объектом на стеке операнда, и пока соответствуют всем другим критериям верификатора, верификатор передаст код.

4.9.6 Исключения и finally

Учитывая фрагмент кода


    ...     try {     startFaucet();     waterLawn();     } finally {     stopFaucet();     }     ...
язык программирования Java гарантирует это stopFaucet вызывается (кран выключается), заканчиваем ли мы поливать лужайку или происходит ли исключение, запуская кран или поливая лужайку. Таким образом, finally пункт, как гарантируют, будет выполнен ли try пункт обычно завершается или завершается резко, выдавая исключение.

Реализовывать try-finally конструкция, компилятор Sun для языка программирования Java использует средства обработки исключений вместе с двумя специальными инструкциями: jsr ("переходят к подпрограмме") и мочат ("возврат из подпрограммы"). finally пункт компилируется как подпрограмма в пределах кода виртуальной машины Java для его метода, очень как код для обработчика исключений. Когда jsr инструкция, которая вызывает подпрограмму, выполняется, это продвигает свой обратный адрес, адрес инструкции после jsr, который выполняется на стек операнда как значение типа returnAddress. Код для подпрограммы хранит обратный адрес в локальной переменной. В конце подпрограммы мочить инструкция выбирает обратный адрес от локальной переменной и передает управление инструкции в обратном адресе.

Управление может быть передано finally пункт ( finally подпрограмма может быть вызвана) несколькими различными способами. Если try пункт обычно завершается, finally подпрограмма вызывается через jsr инструкцию прежде, чем оценить следующее выражение. A break или continue в try пункт, который передает управление вне try пункт выполняет jsr к коду для finally пункт сначала. Если try пункт выполняет a return, скомпилированный код делает следующее:

  1. Сохраняет возвращаемое значение (если любой) в локальной переменной.
  2. Выполняет jsr к коду для finally пункт.
  3. По возврату из finally пункт, возвращает значение, сохраненное в локальной переменной.
Компилятор устанавливает специальный обработчик исключений, который ловит любое исключение, выданное try пункт. Если исключение добавляется try пункт, этот обработчик исключений делает следующее:

  1. Сохраняет исключение в локальной переменной.
  2. Выполняет jsr к finally пункт.
  3. По возврату из finally пункт, повторно бросает исключение.
Для получения дополнительной информации о реализации try-finally создайте, см. Раздел 7.13, "Компилируя finally."

Код для finally пункт представляет специальную проблему верификатору. Обычно, если определенная инструкция может быть достигнута через разнообразные пути, и определенная локальная переменная содержит несовместимые значения через те разнообразные пути, то локальная переменная становится неприменимой. Однако, a finally пункт можно было бы вызвать от нескольких различных мест, приводя к нескольким различным обстоятельствам:

  • У вызова от обработчика исключений может быть определенная локальная переменная, которая содержит исключение.

  • Вызов, чтобы реализовать return может иметь некоторую локальную переменную, которая содержит возвращаемое значение.

  • Вызов от нижней части try у пункта может быть неопределенное значение в той же самой локальной переменной.
Код для finally сам пункт мог бы передать проверку, но после завершения обновления всех преемников мочить инструкции, верификатор отметит, что локальная переменная, что обработчик исключений ожидает содержать исключение, или что код возврата ожидает содержать возвращаемое значение, теперь содержит неопределенное значение.

Проверка кода, который содержит a finally пункт усложняется. Основная идея является следующим:

  • Каждая инструкция отслеживает список целей jsr, должен был достигнуть той инструкции. Для большинства кода этот список пуст. Для инструкций в кодируют для finally пункт, это имеет длину один. Для умножаются вложенный finally код (чрезвычайно редкий!), это может быть более длинно чем один.

  • Поскольку каждая инструкция и каждый jsr должны были достигнуть той инструкции, немного вектора сохраняется всех локальных переменных, к которым получают доступ или измененный начиная с выполнения jsr инструкции.

  • Выполняя мочить инструкцию, которая реализует возврат из подпрограммы, должна быть только одна возможная подпрограмма, из которой может возвращаться инструкция. Две различных подпрограммы не могут "объединиться", их выполнение к синглу мочат инструкцию.

  • Чтобы выполнить анализ потока данных мочить инструкции, специальная процедура используется. Так как верификатор знает подпрограмму, из которой должна возвращаться инструкция, это может найти все jsr инструкции, которые вызывают подпрограмму и объединяют состояние стека операнда и массива локальной переменной во время мочить инструкции в стек операнда и массива локальной переменной инструкций после jsr. Слияние использует специальный набор значений для локальных переменных:

    • Для любой локальной переменной, на которую указывает битовый вектор (созданный выше), был получен доступ или изменен подпрограммой, используйте тип локальной переменной во время мочения.

    • Для других локальных переменных используйте тип локальной переменной перед jsr инструкцией.

4.10 Ограничения виртуальной машины Java

Следующие ограничения виртуальной машины Java неявны в class формат файла:

  • Постоянный пул на интерфейс или на класс ограничивается 65535 записями 16-разрядным constant_pool_count поле ClassFile структура (§4.1). Это действует как внутренний предел на полной сложности единого класса или интерфейса.

  • Объем кода на не -native, не -abstract метод ограничивается 65536 байтами размерами индексов в exception_table из Code атрибут (§4.7.3), в LineNumberTable атрибут (§4.7.8), и в LocalVariableTable атрибут (§4.7.9).

  • Самое большое число локальных переменных в массиве локальных переменных фрейма, создаваемого на вызов метода, ограничивается 65535 размером max_locals элемент Code атрибут (§4.7.3) предоставление кода метода. Отметьте это значения типа long и double как каждый полагают, резервируют две локальных переменные и вносят два модуля к max_locals значение, таким образом, использование локальных переменных тех типов далее уменьшает этот предел.

  • Число полей, которые могут быть объявлены классом или интерфейсом, ограничивается 65535 размером fields_count элемент ClassFile структура (§4.1). Отметьте что значение fields_count элемент ClassFile структура не включает поля, которые наследованы от суперклассов или суперинтерфейсов.

  • Число методов, которые могут быть объявлены классом или интерфейсом, ограничивается 65535 размером methods_count элемент ClassFile структура (§4.1). Отметьте что значение methods_count элемент ClassFile структура не включает методы, которые наследованы от суперклассов или суперинтерфейсов.

  • Число прямых суперинтерфейсов класса или интерфейса ограничивается 65535 размером interfaces_count элемент ClassFile структура (§4.1).

  • Размер стека операнда во фрейме (§3.6) ограничивается 65535 значениями max_stack поле Code_attribute структура (§4.7.3). Отметьте это значения типа long и double как каждый полагают, вносят два модуля к max_stack значение, таким образом, использование значений этих типов на операнде складывают далее, уменьшает этот предел.

  • Число локальных переменных во фрейме (§3.6) ограничивается 65535 max_locals поле Code_attribute структура (§4.7.3) и 16-разрядная индексация локальной переменной набора команд виртуальной машины Java.

  • Число размерностей в массиве ограничивается 255 размером кода операции размерностей multianewarray инструкции и ограничениями, наложенными на multianewarray, anewarray, и newarray инструкции §4.8.2.

  • Число параметров метода ограничивается 255 определением дескриптора метода (§4.3.3), где предел включает один модуль для this в случае экземпляра или интерфейсных вызовов метода. Отметьте, что дескриптор метода определяется с точки зрения понятия длины параметра метода в который параметр типа long или double вносит два модуля длине, таким образом, параметры этих типов далее уменьшают предел.

  • Длина имен полей и имен методов, поля и дескрипторов метода, и других постоянных строковых значений ограничивается 65535 символами 16-разрядным без знака length элемент CONSTANT_Utf8_info структура (§4.4.7). Отметьте, что предел находится на числе байтов в кодировании а не на числе закодированных символов. UTF-8 кодирует некоторые символы, используя два или три байта. Таким образом строки, включающие многобайтовые символы, далее ограничиваются.

1 реализация виртуальной машины Java выпуска 1.0.2 JDK Sun поддерживает class версии формата файла 45.0 до 45.3 включительно. Выпуски 1.1. X JDK Sun могут поддерживать class форматы файлов версий в диапазоне 45.0 до 45.65535 включительно. Реализации версии 1.2 Java 2 платформы могут поддерживать class форматы файлов версий в диапазоне 45.0 до 46.0 включительно.

2 Ретроспективно, делающие 8-байтовые константы берут две постоянных записи пула, был плохой выбор.

3 первый выпуск Спецификации языка JavaTM, требуемой это"com"будьте в верхнем регистре в этом примере. Второй выпуск будет инвертировать то соглашение и использовать нижний регистр.

4 факт это end_pc является монопольным, историческая ошибка в проекте виртуальной машины Java: если код виртуальной машины Java для метода точно 65535 байтов длиной и заканчивается инструкцией, которая 1 байт длиной, то та инструкция не может быть защищена обработчиком исключений. Разработчик компилятора может работать вокруг этой ошибки, ограничивая максимальный размер сгенерированного кода виртуальной машины Java для любого метода, метода инициализации экземпляра, или статического инициализатора (размер любого code массив) к 65534 байтам.

5 InnerClasses атрибут был представлен в выпуске 1.1 JDK, чтобы поддерживать вложенные классы и интерфейсы.

6 Synthetic атрибут был представлен в выпуске 1.1 JDK, чтобы поддерживать вложенные классы и интерфейсы.

7 Deprecated атрибут был представлен в выпуске 1.1 JDK, чтобы поддерживать @deprecated тег в комментариях для документации.

Содержание | Предыдущий | Следующий | Индекс

Спецификация Виртуальной машины JavaTM
Авторское право © Sun Microsystems, Inc 1999 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к jvm@java.sun.com



Spec-Zone.ru - all specs in one place



free hit counter