Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Индекс | Спецификация Виртуальной машины JavaTM |
ГЛАВА 4
Эта глава описывает виртуальную машину Java class
формат файла. Каждый class
файл содержит один тип Java, или класс или интерфейс. Совместимые реализации виртуальной машины Java должны быть способными к контакту со всеми class
файлы, которые соответствуют спецификации, обеспеченной этой книгой.
A class
файл состоит из потока 8-разрядных байтов. Все 16-разрядные, 32-разрядные, и 64-разрядные количества создаются, читая в два, четыре, и восемь последовательных 8-разрядных байтов, соответственно. Многобайтовые элементы данных всегда сохранены в порядке с обратным порядком байтов, где высокие байты на первом месте. В Java этот формат поддерживается интерфейсами java.io.DataInput
и java.io.DataOutput
и классы такой как java.io.DataInputStream
и java.io.DataOutputStream
.
Эта глава определяет свой собственный набор типов данных, представляющих Java class
данные файла: типы u1
, u2
, и u4
представьте без знака - два - или четырехбайтовое количество, соответственно. В Java эти типы могут быть считаны методами такой как readUnsignedByte
, readUnsignedShort
, и readInt
из интерфейса java.io.DataInput
.
Java class
формат файла представляется, используя псевдоструктуры, записанные в нотации структуры подобной C. Избегать беспорядка с полями классов виртуальной машины Java и экземпляров класса, содержания структур, описывающих Java class
формат файла упоминается как элементы. В отличие от полей структуры C, последовательные элементы сохранены в Java class
зарегистрируйте последовательно, не дополняя или выравнивание.
Таблицы переменного размера, состоя из элементов переменного размера, используются в нескольких class
файловые структуры. Хотя мы будем использовать синтаксис массива подобный C, чтобы обратиться к табличным элементам, факт, что таблицы являются потоками структур переменного размера, означает, что не возможно непосредственно преобразовать табличный индекс в байтовое смещение в таблицу.
Где мы именуем структуру данных как массив, это - буквально массив.
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
структура следующие: minor_version, major_versionmagic
элемент предоставляет магическое число, идентифицирующееclass
формат файла; у этого есть значение0xCAFEBABE
.
Значенияconstant_pool_countminor_version
иmajor_version
элементы являются номерами вспомогательной версии и номерами основной версии компилятора, который произвел этоclass
файл. Реализация виртуальной машины Java обычно поддерживаетclass
файлы, имеющие данный номер основной версии и номера вспомогательной версии0
через некоторую детальminor_version
.Если реализация виртуальной машины Java поддерживает некоторый диапазон номеров вспомогательной версии и a
class
с файлом той же самой основной версии, но более высокой вспомогательной версии встречаются, виртуальная машина Java не должна попытаться выполнить более новый код. Однако, если номер основной версии не отличается, будет выполнимо реализовать новую виртуальную машину Java, которая может выполнить код вспомогательных версий до и включая тот из более нового кода.Виртуальная машина Java не должна попытаться выполнить код с различной основной версией. Изменение номера основной версии указывает на главное несовместимое изменение, тот, который требует существенно различной виртуальной машины Java.
В Наборе Разработчика Java Sun (JDK) 1.0.2 выпуска, задокументированные этой книгой, значением
major_version
45
. Значениеminor_version
3
. Только Sun может определить значение новыхclass
номера версий файла.
Значениеconstant_pool []constant_pool_count
элемент должен быть больше чем нуль. Это подает число записейconstant_pool
таблицаclass
файл, гдеconstant_pool
запись в индексном нуле включается в количество, но не присутствует вconstant_pool
таблица файла класса. Aconstant_pool
индекс считают допустимым, если это больше чем нуль и меньше чемconstant_pool_count
.
access_flagsconstant_pool
таблица структур переменной длины (§4.4) представление различных строковых констант, имен классов, имен полей, и других констант, которые упоминаются в пределахClassFile
структура и ее подструктуры.Первая запись
constant_pool
таблица,constant_pool[0]
, резервируется для внутреннего пользования реализацией виртуальной машины Java. Та запись не присутствует вclass
файл. Первая запись вclass
файлconstant_pool[1]
.Каждый из
constant_pool
записи таблицы в индексах1
черезconstant_pool_count-1
структура переменной длины (§4.4), чей формат обозначается его первым байтом "тега".
Значениеthis_classaccess_flags
элемент является маской модификаторов, используемых с классом и интерфейсными объявлениями.access_flags
модификаторы показывают в Таблице 4.1.Интерфейс отличает
ACC_INTERFACE
устанавливаемый флаг. ЕслиACC_INTERFACE
не устанавливается, этот файл класса определяет класс, не интерфейс.Интерфейсы могут только использовать флаги, обозначенные в Таблице 4.1 как использующийся интерфейсами. Классы могут только использовать флаги, обозначенные в Таблице 4.1 как использующийся классами. Интерфейс неявно
abstract
(§2.13.1);ACC_ABSTRACT
флаг должен быть установлен. Интерфейс не может бытьfinal
; его реализация никогда не могла завершаться (§2.13.1), если бы это было, таким образом, у этого не могло бытьACC_FINAL
флаг устанавливается.Флаги
ACC_FINAL
иACC_ABSTRACT
не может оба быть установлен для класса; реализация такого класса никогда не могла завершаться (§2.8.2).Установка
ACC_SUPER
флаг направляет виртуальную машину Java который из двух альтернативных семантик для ее invokespecial инструкции, чтобы выразить; это существует для обратной совместимости для кода, скомпилированного более старыми компиляторами Java Sun. Все новые реализации виртуальной машины Java должны реализовать семантику для invokespecial, задокументированного в Главу 6, "Набор команд виртуальной машины Java." Все новые компиляторы к набору команд виртуальной машины Java должны установитьACC_SUPER
флаг. Более старые компиляторы Java Sun генерируютClassFile
флаги сACC_SUPER
сброс. Более старые реализации виртуальной машины Java Sun игнорируют флаг, если он устанавливается.Все неиспользованные биты
access_flags
элемент, включая не присвоенных в Таблице 4.1, резервируется для будущего использования. Они должны быть обнулены в сгенерированномclass
файлы и должны быть проигнорированы реализациями виртуальной машины Java.
Значениеsuper_classthis_class
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Class_info
(§4.4.1) структура, представляющая класс или интерфейс, определяется этимclass
файл.
Для класса, значенияinterfaces_countsuper_class
элемент или должен быть нулем или должен быть допустимым индексом вconstant_pool
таблица. Если значениеsuper_class
элемент является ненулевым,constant_pool
запись по тому индексу должна быть aCONSTANT_Class_info
(§4.4.1) структура, представляющая суперкласс класса, определяется этимclass
файл. Ни суперкласс, ни любой из его суперклассов не могут быть afinal
класс.Если значение
super_class
нуль, тогда этоclass
файл должен представить классjava.lang.Object
, единственный класс или интерфейс без суперкласса.Для интерфейса, значения
super_class
должен всегда быть допустимый индекс вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Class_info
структура, представляющая классjava.lang.Object
.
Значениеинтерфейсы []interfaces_count
элемент дает число прямых суперинтерфейсов этого класса или интерфейсного типа.
Каждое значение вfields_countinterfaces
массив должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись в каждом значенииinterfaces[
я]
, где0
<I £ interfaces_count
, должен быть aCONSTANT_Class_info
структура (§4.4.1), представляющая интерфейс, который является прямым суперинтерфейсом этого класса или интерфейсного типа, в слева направо порядок, данный в источнике для типа.
Значениеполя []fields_count
элемент дает числоfield_info
структуры вfields
таблица.field_info
(§4.5) структуры представляют все поля, и переменные класса и переменные экземпляра, объявленные этим классом или интерфейсным типом.
Каждое значение вmethods_countfields
таблица должна быть переменной длинойfield_info
(§4.5) структура, дающая полное описание поля в классе или интерфейсном типе.fields
таблица включает только те поля, которые объявляются этим классом или интерфейсом. Это не включает поля представления элементов, которые наследованы от суперклассов или суперинтерфейсов.
Значениеметоды []methods_count
элемент дает числоmethod_info
структуры вmethods
таблица.
Каждое значение вattributes_countmethods
таблица должна быть переменной длинойmethod_info
(§4.6) структура, дающая полное описание и виртуальную машину Java, кодируют для метода в классе или интерфейсе.
method_info
структуры представляют все методы, оба метода экземпляра и, для классов, класс (static
) методы, объявленные этим классом или интерфейсным типом.methods
таблица только включает те методы, которые явно объявляются этим классом. У интерфейсов есть только единственный метод<clinit>
, интерфейсный метод инициализации (§3.8).methods
таблица не включает методы представления элементов, которые наследованы от суперклассов или суперинтерфейсов.
Значениеатрибуты []attributes_count
элемент дает число атрибутов (§4.7) вattributes
таблица этого класса.
Каждое значениеattributes
таблица должна быть структурой атрибута переменной длины. AClassFile
у структуры может быть любое число атрибутов (§4.7) связанный с этим.Единственный атрибут, определенный этой спецификацией для
attributes
таблица aClassFile
структураSourceFile
атрибут (§4.7.2).Реализация виртуальной машины Java обязана тихо игнорировать любые атрибуты в
attributes
таблица aClassFile
структура, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантикуclass
файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).
class
файловые структуры всегда представляются в полностью определенной форме (§2.7.9). Эти имена классов всегда представляются как CONSTANT_Utf8_info
(§4.4.7) структуры, и на них ссылаются от тех CONSTANT_NameAndType_info
структуры (§4.4.6), у которых есть имена классов как часть их дескриптора (§4.3), так же как от всех CONSTANT_Class_info
(§4.4.1) структуры. По историческим причинам точный синтаксис полностью определенных имен классов, которые появляются в class
файловые структуры отличаются от знакомого Java полностью определенное имя класса, задокументированное в §2.7.9. Во внутренней форме, периоды ASCII ('
.'
) это обычно разделяет идентификаторы (§2.2), которые составляют полностью определенное имя, заменяются наклонными чертами вправо ASCII ('/'
). Например, нормальное полностью определенное имя класса Thread
java.lang.Thread
. В форме, используемой в дескрипторах в class
файлы, ссылка на имя класса Thread
реализуется, используя a CONSTANT_Utf8_info
структура, представляющая строку "java/lang/Thread"
.
FieldType
FieldType
BaseType
BObjectType:
L <имя класса>;ArrayType:
[ComponentTypeСимволы BaseType, L и; из ObjectType, и [ArrayType все символы ASCII. <Имя класса> представляет полностью определенное имя класса, например,
java.lang.Thread
. По историческим причинам это сохранено в a class
файл в измененной внутренней форме (§4.2).Значение типов поля следующие:
BНапример, дескрипторbyte
signed byte
Cchar
character
Ddouble
double-precision IEEE 754 float
Ffloat
single-precision IEEE 754 float
Iint
integer
Jlong
long integer
L<classname>;... an instance of the class
Sshort
signed short
Zboolean
true
orfalse
[... one array dimension
int
переменная экземпляра - просто я. Дескриптор переменной экземпляра типа Object
Ljava/lang/Object;. Отметьте что внутренняя форма полностью определенного имени класса для класса Object
используется. Дескриптор переменной экземпляра, которая является многомерным double
массив, double d[][][];
[[[D
FieldTypeДескриптор метода представляет параметры, которые метод берет и значение, которое это возвращает:
(ParameterDescriptor *) ReturnDescriptorДескриптор возврата представляет возвращаемое значение от метода. Это - серия символов, сгенерированных грамматикой:
FieldTypeСимвол V указывает, что метод не возвращает значения (его тип возврата
void
). Иначе, дескриптор указывает на тип возвращаемого значения.
Допустимый дескриптор метода Java должен представить 255 или меньше слов параметров метода, где тот предел включает слово для this
в случае вызовов метода экземпляра. Предел находится на числе слов параметров метода а не на числе параметров непосредственно; параметры типа long
и double
каждое использование два слова.
Например, дескриптор метода для метода
Object mymethod(int i, double d, Thread t)
(IDLjava/lang/Thread;)Ljava/lang/Object;Отметьте что внутренние формы полностью определенных имен классов
Thread
и Object
используются в дескрипторе метода. Дескриптор метода для mymethod
то же самое ли mymethod
static
или метод экземпляра. Хотя метод экземпляра передают this
, ссылка на текущий экземпляр класса, в дополнение к его намеченным параметрам, тот факт не отражается в дескрипторе метода. (Ссылка на this
не передается к a static
метод.) Ссылка на this
передается неявно инструкциями вызова метода виртуальной машины Java, используемой, чтобы вызвать методы экземпляра.
constant_pool
у записей таблицы есть следующий общий формат:
cp_info {
Каждый элемент вu1 tag;
u1 info[];
}
constant_pool
таблица должна начаться с 1-байтового тега, указывающего отчасти cp_info
запись. Содержание info
массив меняется в зависимости от значения tag
. Допустимые теги и их значения перечисляются в Таблице 4.2CONSTANT_Class_info
структура используется, чтобы представить класс или интерфейс:
CONSTANT_Class_info {
Элементыu1 tag;
u2 name_index;
}
CONSTANT_Class_info
структура является следующим: name_indextag
у элемента есть значениеCONSTANT_Class
(7
).
ЗначениеПоскольку массивы являются объектами, коды операций anewarray и multianewarray могут сослаться на массив "классы" черезname_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
структура (§4.4.7), представляющая допустимое полностью определенное имя класса Java (§2.8.1), который был преобразован вclass
внутренняя форма файла (§4.2).
CONSTANT_Class_info
(§4.4.1) структуры в constant_pool
таблица. В этом случае имя класса является дескриптором типа массива. Например, имя класса, представляющее двумерное int
тип массива;
int[][]
[[I
Имя класса, представляющее массив типа класса Thread
; Thread[]
[Ljava.lang.Thread;
У допустимого дескриптора типа массива Java должно быть 255 или меньше размерностей массива.
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;
}
class_indextag
элемент aCONSTANT_Fieldref_info
у структуры есть значениеCONSTANT_Fieldref
(9
).
tag
элемент aCONSTANT_Methodref_info
у структуры есть значениеCONSTANT_Methodref
(10
).
tag
элемент aCONSTANT_InterfaceMethodref_info
у структуры есть значениеCONSTANT_InterfaceMethodref
(11
).
Значениеname_and_type_indexclass_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Class_info
структура (§4.4.1), представляющая класс или интерфейсный тип, который содержит объявление поля или метода.
class_index
элемент aCONSTANT_Fieldref_info
или aCONSTANT_Methodref_info
структура должна быть типом класса, не интерфейсным типом.class_index
элемент aCONSTANT_InterfaceMethodref_info
структура должна быть интерфейсным типом, который объявляет данный метод.
Значениеname_and_type_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_NameAndType_info
(§4.4.6) структура. Этоconstant_pool
запись указывает на имя и дескриптор поля или метода.Если имя метода a
CONSTANT_Methodref_info
илиCONSTANT_InterfaceMethodref_info
начинается с a'<'
('u003c'
), тогда имя должно быть одним из специальных внутренних методов (§3.8), также<init>
или<clinit>
. В этом случае метод не должен возвратить значение.
CONSTANT_String_info
структура используется, чтобы представить постоянные объекты типа java.lang.String
:
CONSTANT_String_info {
Элементыu1 tag;
u2 string_index;
}
CONSTANT_String_info
структура следующие: string_indextag
элементCONSTANT_String_info
у структуры есть значениеCONSTANT_String
(8
).
Значениеstring_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.3) тех, структура, представляющая последовательность символов, к которыйjava.lang.String
объект состоит в том, чтобы быть инициализирован.
CONSTANT_Integer_info
и CONSTANT_Float_info
структуры представляют числовые четыре байта (int
и float
) константы:
CONSTANT_Integer_info {
Элементы этих структур следующие:u1 tag;
u4 bytes;
}
CONSTANT_Float_info {
u1 tag;
u4 bytes;
}
байтыtag
элементCONSTANT_Integer_info
у структуры есть значениеCONSTANT_Integer
(3
).
tag
элементCONSTANT_Float_info
у структуры есть значениеCONSTANT_Float
(4
).
bytes
элементCONSTANT_Integer_info
структура содержит значениеint
постоянный. Байты значения сохранены в обратном порядке байтов (высокий байт сначала) порядок.
bytes
элементCONSTANT_Float_info
структура содержит значениеfloat
постоянный в IEEE 754 "единственный формат с плавающей точкой" разрядное расположение. Байты значения сохранены в обратном порядке байтов (высокий байт сначала) порядок, и сначала преобразовываются вint
параметр. Затем:
- Если параметр
0x7f800000
,float
значение будет положительной бесконечностью.- Если параметр
0xff800000
,float
значение будет отрицательной бесконечностью.- Если параметр находится в диапазоне
0x7f800001
через0x7fffffff
или в диапазоне0xff800001
через0xffffffff
,float
значением будет НЭН.- Во всех других случаях позволить
s
,e
, иm
будьте тремя значениями, которые могли бы быть вычислены
int s = ((bytes >> 31) == 0) ? 1 : -1;
int e = ((bytes >> 23) & 0xff);
int m = (e == 0) ?
(bytes & 0x7fffff) << 1 :
(bytes & 0x7fffff) | 0x800000;
Затемfloat
значение равняется результату математического выражения
.
CONSTANT_Long_info
и CONSTANT_Double_info
представьте числовые восемь байтов (long
и double
) константы:
CONSTANT_Long_info {
Все восьмибайтовые константы приводят две записи в рабочее состояние вu1 tag;
u4 high_bytes;
u4 low_bytes;
}
CONSTANT_Double_info {
u1 tag;
u4 high_bytes;
u4 low_bytes;
}
constant_pool
таблица class
файл, так же как в версии в памяти постоянного пула, который создается когда a class
файл читается. Если a CONSTANT_Long_info
или CONSTANT_Double_info
структура является элементом в constant_pool
таблица по индексу n, тогда следующий допустимый элемент в пуле располагается по индексу n+2. constant_pool
индекс n+1 нужно считать недопустимым и не должен использоваться 1Элементы этих структур следующие:
high_bytes, low_bytestag
элементCONSTANT_Long_info
у структуры есть значениеCONSTANT_Long
(5
).
tag
элементCONSTANT_Double_info
у структуры есть значениеCONSTANT_Double
(6
).
Без знакаhigh_bytes
иlow_bytes
элементыCONSTANT_Long
структура вместе содержит значениеlong
постоянный ((long
)high_bytes
<< 32) +low_bytes
, где байты каждого изhigh_bytes
иlow_bytes
сохранены в обратном порядке байтов (высокий байт сначала) порядок.
high_bytes
иlow_bytes
элементыCONSTANT_Double_info
структура содержитdouble
значение в IEEE 754 "двойной формат с плавающей точкой" разрядное расположение. Байты каждого элемента сохранены в обратном порядке байтов (высокий байт сначала) порядок.high_bytes
иlow_bytes
элементы сначала преобразовываются в along
параметр. Затем:
- Если параметр
0x7f80000000000000L
,double
значение будет положительной бесконечностью.- Если параметр
0xff80000000000000L
,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
значение математического выражения
.
CONSTANT_NameAndType_info
структура используется, чтобы представить поле или метод, не указывая, какому классу или интерфейсному типу это принадлежит:
CONSTANT_NameAndType_info {
Элементыu1 tag;
u2 name_index;
u2 descriptor_index;
}
CONSTANT_NameAndType_info
структура следующие: name_indextag
элементCONSTANT_NameAndType_info
у структуры есть значениеCONSTANT_NameAndType
(12
).
Значениеdescriptor_indexname_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая допустимое имя поля Java или имя метода (§2.7) сохраненный как простое (не полностью определенный) имя (§2.7.1), то есть, как идентификатор Java.
Значениеdescriptor_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая допустимый полевой дескриптор Java (§4.3.2) или дескриптор метода (§4.3.3).
CONSTANT_Utf8_info
структура используется, чтобы представить постоянные строковые значения. Строки UTF-8 кодируются так, чтобы символьные последовательности, которые содержат только ненулевые символы ASCII, могли быть представлены, используя только один байт за символ, но символы до 16 битов могут быть представлены. Все символы в диапазоне 'u0001'
к 'u007F'
представляются единственным байтом:
0 | биты 0-7 |
Семь битов данных в байте дают значение представленного символа. Нулевой символ ('u0000'
) и символы в диапазоне 'u0080'
к 'u07FF'
представляются парой байтов x и y:
x: | 1 | 1 | 0 | биты 6-10 | y: | 1 | 0 | биты 0-5 |
Байты представляют символ со значением ((x & 0x1f
) << 6
) + (y & 0x3f
).
Символы в диапазоне 'u0800'
к 'uFFFF'
представляются на три байта x, y, и z:
x: | 1 | 1 | 1 | 0 | биты 12-15 | y: | 1 | 0 | биты 6-11 | z: | 1 | 0 | биты 0-5 |
Символ со значением ((x & 0xf
) << 12
) + ((y & 0x3f
) << 6
) + (z & 0x3f
) представляется байтами.
Байты многобайтовых символов сохранены в class
файл в обратном порядке байтов (высокий байт сначала) порядок.
Есть два различия между этим форматом и "стандартным" форматом UTF-8. Во-первых, нулевой байт (byte)0
кодируется, используя двухбайтовый формат, а не однобайтовый формат, так, чтобы виртуальная машина Java, которую никогда не встраивали строки UTF-8, обнулила. Во-вторых, только однобайтовое, два байта, и трехбайтовые форматы используются. Виртуальная машина Java не распознает дольше форматы UTF-8.
Для получения дополнительной информации относительно формата UTF-8, см. Файловую систему Безопасный Формат Преобразования UCS (FSS_UTF), X/Open Предварительная Спецификация, X/Open Company Ltd., Номер документа: P316. Эта информация также появляется в ISO/IEC 10646, Приложении P.
CONSTANT_Utf8_info {
Элементыu1 tag;
u2 length;
u1 bytes[length];
}
CONSTANT_Utf8_info
структура является следующим: длинаtag
элементCONSTANT_Utf8_info
у структуры есть значениеCONSTANT_Utf8
(1
).
Значениебайты []length
элемент подает число байтовbytes
массив (не длина получающейся строки). Строки вCONSTANT_Utf8_info
структура не завершается нулем.
bytes
массив содержит байты строки. Ни у какого байта не может быть значения(byte)0
или(byte)0xf0
-(byte)0xff
.
field_info
структура. Формат этой структуры
field_info {
Элементыu2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
field_info
структура следующие: Значениеname_indexaccess_flags
элемент является маской модификаторов, используемых, чтобы описать право доступа к и свойства поля.access_flags
модификаторы показывают в Таблице 4.3.Поля интерфейсов могут только использовать флаги, обозначенные в Таблице 4.3 как использующийся любым полем. Поля классов могут использовать любой из флагов в Таблице 4.3.
Все неиспользованные биты
access_flags
элемент, включая не присвоенных в Таблице 4.3, резервируется для будущего использования. Они должны быть обнулены в сгенерированномclass
файлы и должны быть проигнорированы реализациями виртуальной машины Java.У полей класса может быть самое большее один из флагов
ACC_PUBLIC
,ACC_PROTECTED
, иACC_PRIVATE
набор (§2.7.8). У поля класса, возможно, нет обоихACC_FINAL
иACC_VOLATILE
набор (§2.9.1).Каждое интерфейсное поле неявно
static
иfinal
(у §2.13.4) и должны быть обаACC_STATIC
иACC_FINAL
флаги устанавливаются. Каждое интерфейсное поле неявноpublic
(у §2.13.4) и должен бытьACC_PUBLIC
флаг устанавливается.
Значениеdescriptor_indexname_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
структура (§4.4.7), которая должна представить допустимое имя поля Java (§2.7) сохраненный как простое (не полностью определенный) имя (§2.7.1), то есть, как идентификатор Java.
Значениеattributes_countdescriptor_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8
структура (§4.4.7), которая должна представить допустимый полевой дескриптор Java (§4.3.2).
Значениеатрибуты []attributes_count
элемент указывает на число дополнительных атрибутов (§4.7) этого поля.
Каждое значениеattributes
таблица должна быть структурой атрибута переменной длины. У поля может быть любое число атрибутов (§4.7) связанный с этим.Единственный атрибут, определенный для
attributes
таблица afield_info
структура этой спецификациейConstantValue
атрибут (§4.7.3).Реализация виртуальной машины Java должна распознать
ConstantValue
атрибуты вattributes
таблица afield_info
структура. Реализация виртуальной машины Java обязана тихо игнорировать любые другие атрибуты вattributes
таблица, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантикуclass
файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).
<init>
, описывается переменной длиной method_info
структура. У структуры есть следующий формат:
method_info {
Элементыu2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
method_info
структура следующие: Значениеname_indexaccess_flags
элемент является маской модификаторов, используемых, чтобы описать право доступа к и свойства метода или метода инициализации экземпляра (§3.8).access_flags
модификаторы показывают в Таблице 4.4.Методы в интерфейсах могут только использовать флаги, обозначенные в Таблице 4.4 как использующийся любым методом. Класс и методы экземпляра (§2.10.3) могут использовать любой из флагов в Таблице 4.4. Методы инициализации экземпляра (§3.8) могут только использовать
ACC_PUBLIC
,ACC_PROTECTED
, иACC_PRIVATE
.Все неиспользованные биты
access_flags
элемент, включая не присвоенных в Таблице 4.4, резервируется для будущего использования. Они должны быть обнулены в сгенерированномclass
файлы и должны быть проигнорированы реализациями виртуальной машины Java.Самое большее один из флагов
ACC_PUBLIC
,ACC_PROTECTED
, иACC_PRIVATE
может быть установлен для любого метода. Класс и методы экземпляра, возможно, не используютACC_ABSTRACT
вместе сACC_FINAL
,ACC_NATIVE
, илиACC_SYNCHRONIZED
(то есть,native
иsynchronized
методы требуют реализации). Класс или метод экземпляра, возможно, не используютACC_PRIVATE
сACC_ABSTRACT
(то есть, aprivate
метод не может быть переопределен, таким образом, такой метод никогда не мог реализовываться или использоваться). Класс или метод экземпляра, возможно, не используютACC_STATIC
сACC_ABSTRACT
(то есть, astatic
метод неявноfinal
и таким образом не может быть переопределен, таким образом, такой метод никогда не мог реализовываться или использоваться).Класс и интерфейсные методы инициализации (§3.8), то есть, методы называют
<clinit>
, вызываются неявно виртуальной машиной Java; значение ихaccess_flags
элемент игнорируется.Каждый интерфейсный метод неявно
abstract
, и, имеют - такжеACC_ABSTRACT
флаг устанавливается. Каждый интерфейсный метод неявноpublic
(§2.13.5), и, имеют - такжеACC_PUBLIC
флаг устанавливается.
Значениеdescriptor_indexname_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая любые из специальных внутренних имен методов (§3.8), также<init>
или<clinit>
, или допустимое имя метода Java (§2.7), сохраненный как простое (не полностью определенный) имя (§2.7.1).
Значениеattributes_countdescriptor_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая допустимый дескриптор метода Java (§4.3.3).
Значениеатрибуты []attributes_count
элемент указывает на число дополнительных атрибутов (§4.7) этого метода.
Каждое значениеattributes
таблица должна быть структурой атрибута переменной длины. У метода может быть любое число дополнительных атрибутов (§4.7) связанный с этим.Единственные атрибуты, определенные этой спецификацией для
attributes
таблица amethod_info
структураCode
(§4.7.4) иExceptions
(§4.7.5) атрибуты.Реализация виртуальной машины Java должна распознать
Code
(§4.7.4) иExceptions
(§4.7.5) атрибуты. Реализация виртуальной машины Java обязана тихо игнорировать любые другие атрибуты вattributes
таблица amethod_info
структура, которую это не распознает. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантикуclass
файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).
ClassFile
(§4.1), field_info
(§4.5), method_info
(§4.6), и Code_attribute
(§4.7.4) структуры 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
(§4.4.7) строка, представляющая имя атрибута. Значение attribute_length
элемент указывает на продолжительность последующей информации в байтах. Длина не включает начальные шесть байтов, которые содержат attribute_name_index
и attribute_length
элементы.
Определенные атрибуты предопределяются как часть class
спецификация файла. Предопределенные атрибуты SourceFile
(§4.7.2), ConstantValue
(§4.7.3), Code
(§4.7.4), Exceptions
(§4.7.5), LineNumberTable
(§4.7.6), и Local
-VariableTable
(§4.7.7) атрибуты. В пределах контекста их использования в этой спецификации, то есть, в attributes
таблицы class
резервируются файловые структуры, в которых они появляются, имена этих предопределенных атрибутов.
Из предопределенных атрибутов, Code
, ConstantValue
, и Exceptions
атрибуты должны быть распознаны и правильно считаны a class
средство чтения файлов для корректной интерпретации class
файл виртуальной машиной Java. Использование остающихся предопределенных атрибутов является дополнительным; a class
средство чтения файлов может использовать информацию, которую они содержат, и иначе должны тихо проигнорировать те атрибуты.
class
файлы, содержащие новые атрибуты в attributes
таблицы class
файловые структуры. Реализациям Виртуальной машины Java разрешают распознать и использовать новые атрибуты, найденные в attributes
таблицы class
файловые структуры. Однако, все атрибуты, не определенные как часть этой спецификации виртуальной машины Java, не должны влиять на семантику класса или интерфейсных типов. Реализации Виртуальной машины Java обязаны тихо игнорировать атрибуты, которые они не распознают. Например, определение нового атрибута, чтобы поддерживать специфичную для поставщика отладку разрешается. Поскольку реализации виртуальной машины Java обязаны игнорировать атрибуты, они не распознают, class
файлы, предназначенные для той определенной реализации виртуальной машины Java, будут применимы другими реализациями, даже если те реализации не могут использовать дополнительную отладочную информацию что class
файлы содержат.
Реализациям Виртуальной машины Java определенно мешают выдать исключение или иначе отказаться использовать class
файлы просто из-за присутствия некоторого нового атрибута. Конечно, инструменты, работающие на class
файлы, возможно, не работают правильно если дано class
файлы, которые не содержат все атрибуты, которых они требуют.
Два атрибута, которые предназначаются, чтобы быть отличными, но которые, оказывается, используют то же самое название атрибута и являются той же самой длины, будут конфликтовать на реализациях, которые распознают любой атрибут. У атрибутов, определенных кроме Sun, должны быть имена, выбранные согласно соглашению о присвоении имен пакета, определенному Спецификацией языка Java. Например, у нового атрибута, определенного Netscape, могло бы быть имя "COM.Netscape.new-attribute"
.
Sun может определить дополнительные атрибуты в будущих версиях этого class
спецификация файла.
SourceFile
атрибут является дополнительным атрибутом фиксированной длины в attributes
таблица ClassFile
(§4.1) структура. Может быть не больше, чем один SourceFile
атрибут в attributes
таблица данного ClassFile
структура. SourceFile
у атрибута есть формат
SourceFile_attribute {
Элементыu2 attribute_name_index;
u4 attribute_length;
u2 sourcefile_index;
}
SourceFile_attribute
структура следующие: Значениеattribute_lengthattribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"SourceFile"
.
Значениеsourcefile_indexattribute_length
элемент aSourceFile_attribute
структура должна быть2
.
Значениеsourcefile_index
элемент должен быть допустимым индексом вconstant_pool
таблица. Постоянная запись пула по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) тех, структура, представляющая строку, дающую имя исходного файла, от который этоclass
файл был скомпилирован.Только имя исходного файла дается
SourceFile
атрибут. Это никогда не представляет имя каталога, содержащего файл или абсолютный путь для файла. Например,SourceFile
атрибут мог бы содержать имя файлаfoo.java
но не путь UNIX/home/lindholm/foo.java
.
ConstantValue
атрибут является атрибутом фиксированной длины, используемым в attributes
таблица field_info
(§4.5) структуры. A ConstantValue
атрибут представляет значение постоянного поля, которое должно быть (явно или неявно) static
; то есть, ACC_STATIC
бит (§Table 4.3) в flags
элемент field_info
структура должна быть установлена. Поле не обязано быть final
. Может быть не больше, чем один ConstantValue
атрибут в attributes
таблица данного field_info
структура. Постоянное поле, представленное field_info
структура присваивается значение, на которое ссылается ConstantValue
припишите как часть его инициализации (§2.16.4). Каждая реализация виртуальной машины Java должна распознать ConstantValue
атрибуты.
ConstantValue
у атрибута есть формат
ConstantValue_attribute {
Элементыu2 attribute_name_index;
u4 attribute_length;
u2 constantvalue_index;
}
ConstantValue_attribute
структура следующие: Значениеattribute_lengthattribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"ConstantValue"
.
Значениеconstantvalue_indexattribute_length
элемент aConstantValue_attribute
структура должна быть2
.
Значениеconstantvalue_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна дать постоянную величину, представленную этим атрибутом.
constant_pool
запись должна иметь тип, соответствующий полю, как показано Таблицей 4.5.
Тип поля Тип записи long
CONSTANT_Long
float
CONSTANT_Float
double
CONSTANT_Double
int
,short
,char
,byte
,boolean
CONSTANT_Integer
java.lang.String
CONSTANT_String
Code
атрибут является атрибутом переменной длины, используемым в attributes
таблица method_info
структуры. A Code
атрибут содержит инструкции виртуальной машины Java и вспомогательную информацию для единственного метода Java, метод инициализации экземпляра (§3.8), или класс или интерфейсный метод инициализации (§3.8). Каждая реализация виртуальной машины Java должна распознать Code
атрибуты. Должен быть точно один Code
атрибут в каждом method_info
структура.
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_lengthattribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"Code"
.
Значениеmax_stackattribute_length
элемент указывает на длину атрибута, исключая начальные шесть байтов.
Значениеmax_localsmax_stack
элемент дает максимальное количество слов на стеке операнда в любой точке во время выполнения этого метода.
Значениеcode_lengthmax_locals
элемент дает число локальных переменных, используемых этим методом, включая параметры, которые передают к методу вызову. Индекс первой локальной переменной0
. Самый большой индекс локальной переменной для значения с одним словомmax_locals-1
. Самый большой индекс локальной переменной для значения с двумя словамиmax_locals-2
.
Значениекод []code_length
элемент подает число байтовcode
массив для этого метода. Значениеcode_length
должно быть больше чем нуль;code
массив не должен быть пустым.
exception_table_lengthcode
массив дает фактические байты кода виртуальной машины Java, которые реализуют метод.Когда
code
массив читается в память на байте адресуемая машина, если первый байт массива будет выровненный на 4-байтовой границе, то tableswitch и lookupswitch 32-разрядные смещения составят выровненные 4 байта; сошлитесь на описания тех инструкций для получения дополнительной информации о последствияхcode
выравнивание массива.Подробные ограничения на содержание
code
массив обширен и дается в отдельном участке (§4.8).
Значениеexception_table []exception_table_length
элемент подает число записейexception_table
таблица.
Каждая запись вstart_pc, end_pcexception_table
массив описывает один обработчик исключений вcode
массив. Каждыйexception_table
запись содержит следующие элементы:
Значения этих двух элементовhandler_pcstart_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
).2
Значениеcatch_typehandler_pc
элемент указывает на запуск обработчика исключений. Значение элемента должно быть допустимым индексом вcode
выстройте, должен быть индекс кода операции инструкции, и должны быть меньше чем значениеcode_length
элемент.
Если значениеattributes_countcatch_type
элемент является ненулевым, это должен быть допустимый индекс вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Class_info
структура (§4.4.1), представляющая класс исключений, что этот обработчик исключений определяется, чтобы поймать. Этот класс должен быть классомThrowable
или один из его подклассов. Обработчик исключений вызовут, только если выданное исключение является экземпляром данного класса или одним из его подклассов.Если значение
catch_type
элемент является нулем, этот обработчик исключений вызывают для всех исключений. Это используется, чтобы реализоватьfinally
(см. Раздел 7.13, "Компилируя наконец").
Значениеатрибуты []attributes_count
элемент указывает на число атрибутовCode
атрибут.
Каждое значениеattributes
таблица должна быть структурой атрибута переменной длины. ACode
у атрибута может быть любое число дополнительных атрибутов, связанных с этим.В настоящий момент,
LineNumberTable
(§4.7.6) иLocalVariableTable
(§4.7.7) атрибуты, оба из которых содержат отладочную информацию, определяются и используются сCode
атрибут.Реализации виртуальной машины Java разрешают тихо проигнорировать любые атрибуты в
attributes
таблица aCode
атрибут. Атрибутам, не определенным в этой спецификации, не позволяют влиять на семантикуclass
файл, но только предоставить дополнительную дескриптивную информацию (§4.7.1).
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_lengthattribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть
CONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"Exceptions"
.
Значениеnumber_of_exceptionsattribute_length
элемент указывает на длину атрибута, исключая начальные шесть байтов.
Значениеexception_index_table []number_of_exceptions
элемент указывает на число записей вexception_index_table
.
Каждое ненулевое значение вМетод должен только выдать исключение, если по крайней мере одному из следующих трех критериев соответствуют:exception_index_table
массив должен быть допустимым индексом вconstant_pool
таблица. Для каждого табличного элемента, еслиexception_index_table[
я] != 0
, где0
I £ <number_of_exceptions
, тогдаconstant_pool
запись по индексуexception_index_table[
я]
должен быть aCONSTANT_Class_info
структура (§4.4.1), представляющая тип класса, который этот метод, как объявляют, бросает.
RuntimeException
или один из его подклассов.
Error
или один из его подклассов.
exception_index_table
выше, или один из их подклассов. throws
пункты, когда классы проверяются. LineNumberTable
атрибут является дополнительным атрибутом переменной длины в attributes
таблица a Code
(§4.7.4) атрибут. Это может использоваться отладчиками, чтобы определить который часть виртуальной машины Java code
массив соответствует данному номеру строки в исходном исходном файле Java. Если LineNumberTable
атрибуты присутствуют в attributes
таблица данного Code
атрибут, тогда они могут появиться в любом порядке. Кроме того, многократный LineNumberTable
атрибуты могут вместе представить данную строку исходного файла Java; то есть, LineNumberTable
атрибуты не должны быть непосредственными с исходными строками 3
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_lengthЗначение
attribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"LineNumberTable"
.
Значениеline_number_table_lengthattribute_length
элемент указывает на длину атрибута, исключая начальные шесть байтов.
Значениеline_number_table []line_number_table_length
элемент указывает на число записей вline_number_table
массив.
Каждая запись вstart_pcline_number_table
массив указывает, что номер строки в исходном исходном файле Java изменяется в поданной точкеcode
массив. Каждая запись должна содержать следующие элементы:
Значениеline_numberstart_pc
элемент должен указать на индекс вcode
массив, в котором начинается код для новой строки в исходном исходном файле Java. Значениеstart_pc
должны быть меньше чем значениеcode_length
элементCode
атрибут которого этоLineNumberTable
атрибут.
Значениеline_number
элемент должен дать соответствующий номер строки в исходном исходном файле Java.
LocalVariableTable
атрибут является дополнительным атрибутом переменной длины a Code
(§4.7.4) атрибут. Это может использоваться отладчиками, чтобы определить значение данной локальной переменной во время выполнения метода. Если 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_lengthattribute_name_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна быть aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая строку"LocalVariableTable"
.
Значениеlocal_variable_table_lengthattribute_length
элемент указывает на длину атрибута, исключая начальные шесть байтов.
Значениеlocal_variable_table []local_variable_table_length
элемент указывает на число записей вlocal_variable_table
массив.
Каждая запись вstart_pc, длинаlocal_variable_table
массив указывает на диапазонcode
выстройте смещения, в пределах которых у локальной переменной есть значение. Это также указывает на индекс в локальные переменные текущего фрейма, в котором может быть найдена та локальная переменная. Каждая запись должна содержать следующие элементы:
У данной локальной переменной должно быть значение в индексах вname_index, descriptor_indexcode
массив в интервале [start_pc
,start_pc+length
], то есть, междуstart_pc
иstart_pc+length
включительно. Значениеstart_pc
должен быть допустимый индекс вcode
массив этогоCode
атрибут кода операции инструкции. Значениеstart_pc+length
должен быть любой допустимый индекс вcode
массив этогоCode
атрибут кода операции инструкции, или первый индекс вне конца этогоcode
массив.
Значениеиндексname_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна содержать aCONSTANT_Utf8_info
(§4.4.7)структура, представляющая допустимое имя локальной переменной Java, сохраненное как простое имя (§2.7.1).
Значение
descriptor_index
элемент должен быть допустимым индексом вconstant_pool
таблица.constant_pool
запись по тому индексу должна содержать aCONSTANT_Utf8_info
(§4.4.7) структура, представляющая допустимый дескриптор для локальной переменной Java. У дескрипторов локальной переменной Java есть та же самая форма как полевые дескрипторы (§4.3.2).
Данная локальная переменная должна быть вindex
в локальных переменных его метода. Если локальная переменная вindex
тип с двумя словами (double
илиlong
), это занимает обоихindex
иindex+1
.
code
массив Code
атрибут a method_info
структура a class
файл. Этот раздел описывает ограничения, связанные с содержанием Code_attribute
структура. class
файл - те, которые определяют отмеченность файла. За исключением статических ограничений на код виртуальной машины Java class
файл, эти ограничения были даны в предыдущем разделе. Статические ограничения на виртуальную машину Java кодируют в a class
файл определяет, как инструкции виртуальной машины Java должны быть размечены в code
массив, и каковы операнды отдельных инструкций должны быть. Статические ограничения на инструкции в code
массив следующие:
code
массив не должен быть пустым, таким образом, code_length
у атрибута не может быть значения 0
.
code
массив начинается по индексу 0
.
code
массив. Экземпляры инструкций, используя зарезервированные коды операций (§6.2), _quick коды операций, задокументированные в Главу 9, "Оптимизация," или любые коды операций, не задокументированные в эту спецификацию, возможно, не появляются в code
массив.
code
массив кроме последнего, индекс кода операции следующей инструкции равняется индексу кода операции текущей команды плюс длина той инструкции, включая все ее операнды. Широкая инструкция обрабатывается как любая другая инструкция в этих целях; код операции, определяющий работу, которую должна изменить широкая инструкция, обрабатывается как один из операндов той широкой инструкции. Тот код операции никогда не должен быть непосредственно достижимым вычислением.
code
массив должен быть байтом по индексу code_length-1
. code
массив следующие: constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Integer
, CONSTANT_Float
, или CONSTANT_String
.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Long
или CONSTANT_double
. Кроме того, последующий постоянный индекс пула должен также быть допустимым индексом в постоянный пул, и постоянная запись пула по тому индексу не должна использоваться.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Fieldref
.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Methodref
.
<init>
, метод инициализации экземпляра (§3.8). Никакой другой метод, имя которого начинается с символа '<'
('u003c'
) может быть вызван инструкциями вызова метода. В частности метод инициализации класса <clinit>
никогда не вызывается явно от инструкций виртуальной машины Java, но только неявно виртуальной машиной Java непосредственно.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_InterfaceMethodref
. Значение nargs операнда каждой invokeinterface инструкции должно быть тем же самым как числом слов параметра, подразумеваемых дескриптором CONSTANT_NameAndType_info
структура, на которую ссылаются CONSTANT_InterfaceMethodref
постоянная запись пула. У четвертого байта операнда каждой invokeinterface инструкции должен быть нуль значения.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Class
.
CONSTANT_Class
constant_pool
запись таблицы, представляющая класс массива. Новая инструкция не может использоваться, чтобы создать массив. Новая инструкция также не может использоваться, чтобы создать интерфейс или экземпляр abstract
во время ссылки выполняется класс, но те проверки.
CONSTANT_Class
операнд, это не должно попытаться создать больше размерностей, чем находятся в типе массива. Операнд размерностей каждой multianewarray инструкции не должен быть нулем.
T_BOOLEAN
(4
), T_CHAR
(5
), T_FLOAT
(6
), T_DOUBLE
(7
), T_BYTE
(8
), T_SHORT
(9
), T_INT
(10
), или T_LONG
(11
).
max_locals-1
.
max_locals-1
.
max_locals-2
.
max_locals-2
. code
массив определяет ограничения на отношения между инструкциями виртуальной машины Java. Структурные ограничения следующие: int
также разрешается работать на значениях типа byte
, char
, и short
. (Как отмечено в §3.11.1, виртуальная машина Java внутренне преобразовывает значения типов byte
, char
, и short
вводить int
.)
long
или double
) будьте инвертированы или разделены. Ни в каком смысле не может слова типа с двумя словами управляться на индивидуально.
max_stack
слова.
<init>
, метод в this
, a private
метод, или метод в суперклассе this
.
<init>
вызывается, неинициализированный экземпляр класса должен быть в соответствующей позиции на стеке операнда. <init>
метод никогда не должен вызываться на инициализированный экземпляр класса.
finally
пункт. Однако, неинициализированный экземпляр класса может быть на стеке операнда в коде, защищенном обработчиком исключений или a finally
пункт. Когда исключение выдается, содержание стека операнда отбрасывается.
Object
, должен вызвать любой другой метод инициализации экземпляра this
или метод инициализации экземпляра ее непосредственного суперкласса super
прежде, чем к его членам экземпляра получают доступ. Однако, это не необходимо в случае класса Object
, у которого нет суперкласса (§2.4.6).
abstract
метод никогда не должен вызываться.
byte
, char
, short
, или int
, только ireturn инструкция может использоваться. Если метод возвращает a float
, long
, или double
, только freturn, lreturn, или dreturn инструкция, соответственно, может использоваться. Если метод возвращает a reference
введите, это должно сделать так использование areturn инструкции, и возвращенное значение должно быть присвоением, совместимым (§2.6.6) с дескриптором возврата (§4.3.3) метода. Все методы инициализации экземпляра, статические инициализаторы, и методы, которые, как объявляют, возвратились void
должен только использовать инструкцию возврата.
protected
поле суперкласса, тогда тип получаемого доступ экземпляра класса должно быть тем же самым как или подкласс текущего класса. Если invokevirtual привык к доступу a protected
метод суперкласса, тогда тип получаемого доступ экземпляра класса должен быть тем же самым как или подкласс текущего класса.
byte
, char
, short
, или int
, тогда значение должно быть int
. Если тип дескриптора float
, long
, или double
, тогда значение должно быть a float
, long
, или double
, соответственно. Если тип дескриптора является a reference
введите, тогда значение должно иметь тип, который является присвоением, совместимым (§2.6.6) с типом дескриптора.
reference
aastore инструкцией должно быть присвоение, совместимое (§2.6.6) с компонентным типом массива.
Throwable
или подклассов Throwable
.
code
массив.
returnAddress
) может быть загружен из локальной переменной.
try
-finally
конструкции изнутри a finally
пункт. Для получения дополнительной информации по подпрограммам виртуальной машины Java см. §4.9.6.)
returnAddress
может быть возвращен к самое большее однажды. Если мочить инструкция возвращается к вопросу в цепочке вызова подпрограммы выше мочить инструкции, соответствующей приведенному примеру типа returnAddress
, тогда тот экземпляр никогда не может использоваться в качестве обратного адреса. class
файлы. Браузер HotJava должен определить ли class
файл был произведен защищенным компилятором Java или противником, пытающимся использовать интерпретатор. Дополнительной проблемой со временем компиляции, проверяя является скос версии. Пользователь, возможно, успешно скомпилировал класс, сказать PurchaseStockOptions
, быть подклассом TradingClass
. Но определение TradingClass
возможно, изменился в пути, который не является совместимым с существующими ранее двоичными файлами со времени, класс был скомпилирован. Методы, возможно, были удалены, или имели свои типы возврата или измененные модификаторы. Поля, возможно, изменили типы или изменились от переменных экземпляра до переменных класса. Модификаторы доступа метода или переменной, возможно, изменились от public
к private
. Для обсуждения этих проблем см. Главу 13, "Совместимость на уровне двоичных кодов," в Спецификации языка Java.
Из-за этих потенциальных проблем виртуальная машина Java должна проверить для себя, что требуемые ограничения держатся class
файлы это пытается соединиться. Правильно написанный эмулятор виртуальной машины Java мог отклонить плохо сформированные инструкции когда a class
файл загружается. Во время выполнения могли быть проверены другие ограничения. Например, реализация виртуальной машины Java могла тегировать данные времени выполнения и иметь каждую проверку инструкции, что ее операнды имеют правильный тип.
Вместо этого реализация виртуальной машины Java Sun проверяет что каждый class
файл, который это считает незащищенным, удовлетворяет необходимые ограничения при соединении времени (§2.16.3). Структурные ограничения на код виртуальной машины Java проверяются, используя простую программу автоматического доказательства теоремы.
Разовая соединением проверка улучшает производительность интерпретатора. Могут быть устранены дорогие проверки, которые должны были бы иначе быть выполнены, чтобы проверить ограничения во время выполнения для каждой интерпретируемой инструкции. Виртуальная машина Java может предположить, что эти проверки были уже выполнены. Например, виртуальная машина Java будет уже знать следующее:
class
верификатор файла независим от любого компилятора Java. Это должно сертифицировать весь код, сгенерированный текущим компилятором Java Sun; это должно также сертифицировать код, который другие компиляторы могут генерировать, так же как код, который не мог возможно генерировать текущий компилятор. Любой class
файл, который удовлетворяет структурные критерии и статические ограничения, будет сертифицирован верификатором.
class
верификатор файла также независим от языка Java. Другие языки могут быть скомпилированы в class
формат, но только передаст проверку, если они удовлетворят те же самые ограничения как a class
файл скомпилирован из источника Java.
class
верификатор файла работает в четырех передачах:
Передача 1: Когда предполагаемое class
файл загружается (§2.16.2) виртуальной машиной Java, виртуальная машина Java сначала гарантирует, что у файла есть основной формат Java class
файл. Первые четыре байта должны содержать правильное магическое число. Все распознанные атрибуты должны иметь надлежащую длину. class
файл не должен быть усеченным или иметь дополнительные байты в конце. Постоянный пул не должен содержать поверхностно неузнаваемую информацию.
В то время как class
проверка файла должным образом происходит во время класса, соединяющегося (§2.16.3), эта проверка на основной class
целостность файла необходима для любой интерпретации class
содержание файла и, как могут полагать, является логически частью процесса проверки.
Передача 2: Когда class
файл соединяется, верификатор выполняет всю дополнительную проверку, которая может быть сделана, не смотря на code
массив Code
атрибут (§4.7.4). Проверки, выполняемые этой передачей, включают следующее:
final
классы не разделяются на подклассы, и это final
методы не переопределяются.
Object)
имеет суперкласс.
CONSTANT_Utf8
представьте ссылку в виде строки в постоянном пуле.
Передача 3: Все еще во время соединения, верификатор проверяет code
массив Code
атрибут для каждого метода class
файл, выполняя анализ потока данных каждого метода. Верификатор гарантирует, что в любой данной точке в программе, независимо от того какой путь выполнения кода берется, чтобы достигнуть той точки:
Передача 4: По причинам эффективности задерживаются определенные тесты, которые могли в принципе быть выполнены в Передаче 3, до первого раза фактически вызывается код для метода. Таким образом, Передача 3 из верификатора избегает загружаться class
файлы, если это не имеет к.
Например, если метод вызывает другой метод, который возвращает экземпляр класса A
, и тот экземпляр только присваивается полю того же самого типа, верификатор не потрудился проверять если класс A
фактически существует. Однако, если это присваивается полю типа B
, определения обоих A
и B
должен быть загружен в гарантировать это A
подкласс B
.
Передача 4 является виртуальной передачей, проверка которой делается соответствующими инструкциями виртуальной машины Java. В первый раз инструкция, что ссылается на тип, выполняется, выполняющаяся инструкция делает следующее:
LinkageError
быть брошенным. Виртуальной машине Java позволяют выполнить любую из Передачи 4 шага, за исключением класса или интерфейсной инициализации, как часть Передачи 3; см. 2.16.1, "Запуск Виртуальной машины" для примера и большего количества обсуждения.
В реализации виртуальной машины Java Sun, после того, как была выполнена проверка, инструкция в коде виртуальной машины Java заменяется альтернативной формой инструкции (см. Главу 9, "Оптимизация"). Например, код операции new
заменяется new_quick
. Эта альтернативная инструкция указывает, что проверка, необходимая этой инструкции, имела место и не должна быть выполнена снова. Последующие вызовы метода таким образом будут быстрее. Это недопустимо для этих альтернативных форм инструкции, чтобы появиться в class
файлы, и с ними никогда не должен встречаться верификатор.
class
проверка файла. Этот раздел смотрит на проверку кода виртуальной машины Java более подробно. Код для каждого метода проверяется независимо. Во-первых, байты, которые составляют код, разбиваются в последовательность инструкций, и индекс в code
массив запуска каждой инструкции размещается в массив. Верификатор тогда проходит через код во второй раз и анализирует инструкции. Во время этой передачи структура данных создается, чтобы содержать информацию о каждой инструкции виртуальной машины Java в методе. Операнды, если таковые вообще имеются, каждой инструкции проверяются, чтобы удостовериться, что они допустимы. Например:
code
массив для метода.
int
или float
, или для экземпляров класса String
; инструкция getfield должна сослаться на поле.
byte
, short
, char
) когда определение значения вводит на стеке операнда. Затем, поток данных анализатор инициализируется. Для первой инструкции метода локальные переменные, которые представляют параметры первоначально, содержат значения типов, обозначенных дескриптором типа метода; стек операнда пуст. Все другие локальные переменные содержат недопустимое значение. Для других инструкций, которые еще не были исследованы, никакая информация не доступна относительно стека операнда или локальных переменных.
Наконец, поток данных анализатор выполняется. Для каждой инструкции "измененный" бит указывает, нужно ли на эту инструкцию смотреть. Первоначально, "измененный" бит только устанавливается для первой инструкции. Поток данных анализатор выполняет следующий цикл:
reference
значения могут появиться в соответствующих местах на двух стеках. В этом случае объединенный стек операнда содержит a reference
к экземпляру первого общего суперкласса или общего суперинтерфейса двух типов. Такой ссылочный тип всегда существует потому что тип Object
супертип всего класса и интерфейсных типов. Если стеки операнда не могут быть объединены, проверка сбоев метода.
Чтобы объединить два состояния локальной переменной, соответствующие пары локальных переменных сравниваются. Если два типа не идентичны, то, если оба не содержат reference
значения, записи верификатора, что локальная переменная содержит неприменимое значение. Если обе из пары локальных переменных содержат reference
значения, объединенное состояние содержит a reference
к экземпляру первого общего суперкласса двух типов.
Если поток данных, анализатор работает на методе, не сообщая об отказе проверки, то метод был успешно проверен Передачей 3 из class
верификатор файла.
Определенные инструкции и типы данных усложняют поток данных анализатор. Мы теперь исследуем каждый из них более подробно.
long
и double
типы каждый берет два последовательных слова на стеке операнда и в локальных переменных. Всякий раз, когда a long
или double
перемещается в локальную переменную, последующая локальная переменная отмечается как содержащий вторую половину a long
или double
. Это специальное значение указывает что все ссылки на long
или double
должен быть через индекс локальной переменной с более низким номером.
Всякий раз, когда любое значение перемещается в локальную переменную, предыдущая локальная переменная исследуется, чтобы видеть, содержит ли это первое слово a long
или a double
. Если так, та предыдущая локальная переменная изменяется, чтобы указать, что она теперь содержит неприменимое значение. Начиная с половины long
или double
был перезаписан, другая половина больше не должна использоваться.
Контакт с 64-разрядными количествами на стеке операнда более прост; верификатор обрабатывает их как единые блоки на стеке. Например, код проверки для dadd кода операции (добавляют два double
значения), проверяет, что лучшие два элемента на стеке имеют оба тип double
. Когда вычисление операнда складывает длину, значения типа long
и double
имейте длину два.
Невведенные инструкции, которые управляют стеком операнда, должны обработать значения типа double
и long
как атомарный. Например, верификатор сообщает об отказе, если главное значение на стеке является a double
и это встречается с инструкцией те, которые выталкивают или копируют. Инструкции pop2 или dup2 должны использоваться вместо этого.
...
может быть реализован следующим:new myClass(i, j, k);
...
...
new #1 // Allocate uninitialized space forЭта последовательность инструкции листы недавно создаваемый и инициализированный объект сверху стека операнда. (Больше примеров компиляции кода Java к набору команд виртуальной машины Java дается в Главе 7, "Компилирующей для виртуальной машины Java.")myClass
dup // Duplicate object on the operand stack iload_1 // Push i iload_2 // Push j iload_3 // Push k invokespecialmyClass.<init>
// Initialize object...
Метод инициализации экземпляра <init>
для класса myClass
рассматривает новый неинициализированный объект как this
параметр в локальной переменной 0
. Это должно или вызвать альтернативный метод инициализации экземпляра для класса myClass
или вызовите метод инициализации суперкласса на this
объект прежде, чем будет позволено сделать что-либо еще с this
.
Делая анализ потока данных методов экземпляра, верификатор инициализирует локальную переменную 0
содержать объект текущего класса, или, например методы инициализации, локальная переменная 0
содержит специальный тип, указывающий на неинициализированный объект. После того, как соответствующий метод инициализации вызывается (от текущего класса или текущего суперкласса) на этом объекте, все возникновения этого специального типа на модели верификатора стека операнда и в локальных переменных заменяются текущим типом класса. Верификатор отклоняет код, который использует новый объект прежде, чем это было инициализировано, или это инициализирует объект дважды. Кроме того, это гарантирует, что каждый нормальный возврат метода или вызвал метод инициализации в классе этого метода или в прямом суперклассе.
Точно так же специальный тип создается и спешил модель верификатора стека операнда как результат новой инструкции виртуальной машины Java. Специальный тип указывает на инструкцию, которой экземпляр класса создавался и тип неинициализированного создаваемого экземпляра класса. Когда метод инициализации вызывается на тот экземпляр класса, все возникновения специального типа заменяются намеченным типом экземпляра класса. Это изменение в типе может распространить к последующим инструкциям, поскольку анализ потока данных продолжается.
Число инструкции должно быть сохранено как часть специального типа, поскольку могут быть многократные еще инициализированные экземпляры существующего класса на стеке операнда когда-то. Например, последовательность инструкции виртуальной машины Java, которая реализует
new InputStream(new Foo(), new InputStream("foo"))
может иметь два неинициализированных экземпляра InputStream
на операнде складывают сразу. Когда метод инициализации вызывается на экземпляр класса, только те возникновения специального типа на стеке операнда или в регистрах, которые являются тем же самым объектом, как экземпляр класса заменяется.
У допустимой последовательности инструкции не должно быть неинициализированного объекта на стеке операнда или в локальной переменной во время назад ответвление, или в локальной переменной в коде, защищенном обработчиком исключений или a finally
пункт. Иначе, окольная часть кода могла бы дурачить верификатор, заставляя думать, это инициализировало экземпляр класса, когда это, фактически, инициализировало экземпляр класса, создаваемый в предыдущей передаче через цикл.
class
верификатор файла, так как они не ставят под угрозу целостность виртуальной машины Java. Пока каждый неисключительный путь к причинам обработчика исключений там, чтобы быть единственным объектом на стеке операнда, и пока соответствуют всем другим критериям верификатора, верификатор передаст код. finally
...
язык Java гарантирует этоtry {
startFaucet();
waterLawn();
} finally {
stopFaucet();
}
...
stopFaucet
вызывается (кран выключается), заканчиваем ли мы поливать лужайку или происходит ли исключение, запуская кран или поливая лужайку. Таким образом, finally
пункт, как гарантируют, будет выполнен ли try
пункт обычно завершается, или завершается резко, выдавая исключение. Реализовывать try-finally
создайте, компилятор Java использует средства обработки исключений вместе с двумя специальными инструкциями jsr ("переход к подпрограмме"), и мочите ("возврат из подпрограммы"). finally
пункт компилируется как подпрограмма в пределах кода виртуальной машины Java для его метода, очень как код для обработчика исключений. Когда jsr инструкция, которая вызывает подпрограмму, выполняется, это продвигает свой обратный адрес, адрес инструкции после jsr, который выполняется на стек операнда как значение типа returnAddress
. Код для подпрограммы хранит обратный адрес в локальной переменной. В конце подпрограммы мочить инструкция выбирает обратный адрес от локальной переменной и передает управление инструкции в обратном адресе.
Управление может быть передано finally
пункт ( finally
подпрограмма может быть вызвана) несколькими различными способами. Если try
пункт обычно завершается, finally
подпрограмма вызывается через jsr инструкцию прежде, чем оценить следующее выражение Java. A break
или continue
в try
пункт, который передает управление вне try
пункт выполняет jsr к коду для finally
пункт сначала. Если try
пункт выполняет a return
, скомпилированный код делает следующее:
finally
пункт.
finally
пункт, возвращает значение, сохраненное в локальной переменной. try
пункт. Если исключение добавляется try
пункт, этот обработчик исключений делает следующее: finally
пункт.
finally
пункт, повторно бросает исключение. try-finally
создайте, см. Раздел 7.13, "Компилируя наконец."
Код для finally
пункт представляет специальную проблему верификатору. Обычно, если определенная инструкция может быть достигнута через разнообразные пути, и определенная локальная переменная содержит несовместимые значения через те разнообразные пути, то локальная переменная становится неприменимой. Однако, a finally
пункт можно было бы вызвать от нескольких различных мест, приводя к нескольким различным обстоятельствам:
return
может иметь некоторую локальную переменную, которая содержит возвращаемое значение.
try
у пункта может быть неопределенное значение в той же самой локальной переменной. finally
сам пункт мог бы передать проверку, но после обновления всех преемников мочить инструкции, верификатор отметит, что локальная переменная, что обработчик исключений ожидает содержать исключение, или что код возврата ожидает содержать возвращаемое значение, теперь содержит неопределенное значение. Проверка кода, который содержит a finally
пункт усложняется. Основная идея является следующим:
finally
пункт, это имеет длину один. Для умножаются вложенный finally
код (чрезвычайно редкий!), это может быть более длинно чем один.
class
Формат файлаconstant_pool_count
поле ClassFile
структура (§4.1). Это действует как внутренний предел на полной сложности единого класса.
exception_table
из Code
атрибут (§4.7.4), в LineNumberTable
атрибут (§4.7.6), и в LocalVariableTable
атрибут (§4.7.7).
max_locals
элемент ClassFile
структура (§4.1). (Вспомните это значения типа long
и double
как полагают, занимают две локальных переменные.)
fields_count
элемент ClassFile
структура (§4.1).
methods_count
элемент ClassFile
структура (§4.1).
max_stack
поле Code_attribute
структура (§4.7.4).
this
в случае вызовов метода экземпляра. Отметьте, что предел находится на числе слов параметров метода, а не на числе параметров непосредственно. Параметры типа long
и double
два слова долго; параметрами всех других типов является одно слово долго.
2 факт это end_pc
является монопольным, историческая ошибка в виртуальной машине Java: если код виртуальной машины Java для метода точно 65535 байтов длиной и заканчивается инструкцией, которая один байт длиной, то та инструкция не может быть защищена обработчиком исключений. Разработчик компилятора может работать вокруг этой ошибки, ограничивая максимальный размер сгенерированного кода виртуальной машины Java для любого метода, метода инициализации экземпляра, или статического инициализатора (размер любого code
массив) к 65534 байтам.
3 javac
компилятор в JDK Sun 1.0.2 выпуска может фактически генерировать LineNumberTable
атрибуты, которые не находятся в порядке номера строки и которые не являются непосредственными с исходными строками. Это неудачно, поскольку мы предпочли бы определять непосредственное, упорядоченное отображение LineNumberTable
атрибуты, чтобы определить источник строк, но должен уступить обратной совместимости.
Содержание | Предыдущий | Следующий | Индекс
Спецификация Виртуальной машины Java
Авторское право © 1996, 1997 Sun Microsystems, Inc. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к jvm@java.sun.com