Spec-Zone .ru
спецификации, руководства, описания, API
|
Содержание | Предыдущий | Следующий | Индекс | Спецификация Виртуальной машины 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, чтобы обратиться к табличным элементам, факт, что таблицы являются потоками структур переменного размера, означает, что не возможно преобразовать табличный индекс непосредственно в байтовое смещение в таблицу.
Где мы именуем структуру данных как массив, это состоит из нуля или более непрерывный фиксированный - измеренные элементы и может быть индексировано как массив.
ClassFile
Структура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_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
элемент дает число 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).
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"
.
class
формат файла используя строки UTF-8 (§4.4.7) и таким образом может быть оттянут, где не далее ограниченный, от всего набора символов Unicode.
FieldType:
BaseType
ObjectType
ArrayType
состояния, что FieldType может представить или BaseType, ObjectType, или ArrayType.
Нетерминальный символ на правой стороне производства, которое сопровождается звездочкой (*), представляет нуль или более возможно различные значения, произведенные из который нетерминальный, добавленный без любого прошедшего пространства. Производство:
MethodDescriptor:
(ParameterDescriptor*) ReturnDescriptor
состояния, что MethodDescriptor представляет левую круглую скобку, сопровождаемую нулем или большим количеством значений ParameterDescriptor, сопровождаемых правой круглой скобкой, сопровождаемой ReturnDescriptor.
FieldType
FieldType
BaseType
BObjectType:
L <имя класса>;ArrayType:
[ComponentTypeСимволы BaseType, L и; из ObjectType, и [ArrayType все символы ASCII. <Имя класса> представляет полностью определенный класс или интерфейсное имя. По историческим причинам это кодируется во внутренней форме (§4.2).
Интерпретация типов поля находится как показано в Таблице 4.2.
Например, дескриптор переменной экземпляра типа int
просто я. Дескриптор переменной экземпляра типа Object
Ljava/lang/Object;. Отметьте что внутренняя форма полностью определенного имени для класса Object
используется. Дескриптор переменной экземпляра, которая является многомерным double
массив,
double d[][][];
[[[D
MethodDescriptor:Дескриптор параметра представляет параметр, который передают методу:
(ParameterDescriptor*) ReturnDescriptor
ParameterDescriptor:Дескриптор возврата представляет тип значения, возвращенного из метода. Это - серия символов, сгенерированных грамматикой:
FieldType
ReturnDescriptor:Символ V указывает, что метод не возвращает значения (его тип возврата
FieldType
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, используемой, чтобы вызвать методы экземпляра.
constant_pool
таблица. Все constant_pool
у записей таблицы есть следующий общий формат:
Каждый элемент в
cp_info {
u1 tag;
u1 info[];
}
constant_pool
таблица должна начаться с 1-байтового тега, указывающего отчасти cp_info
запись. Содержание info
массив меняется в зависимости от значения tag
. Допустимые теги и их значения перечисляются в Таблице 4.3. Каждый байт тега должен сопровождаться на два или больше байта, дающие информацию об определенной константе. Формат дополнительной информации меняется в зависимости от значения тега.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 или меньше размерностей. 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). Такой метод не должен возвратить значение.
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
объект состоит в том, чтобы быть инициализирован.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
постоянные биты. Затем:
0x7f800000
, float
значение будет положительной бесконечностью. 0xff800000
, float
значение будет отрицательной бесконечностью. 0x7f800001
через 0x7fffffff
или в диапазоне 0xff800001
через 0xffffffff
, float
значением будет НЭН. s
, e
, и m
будьте тремя значениями, которые могли бы быть вычислены из битов: int s = ((
bits>> 31) == 0) ? 1 : -1;
int e = ((
bits>> 23) & 0xff);
int m = (e == 0) ?
(
bits& 0x7fffff) << 1 :
(
bits& 0x7fffff) | 0x800000;
Then thefloat
value equals the result of the mathematical expressions·m·2e-150
.
CONSTANT_Long_info
и CONSTANT_Double_info
СтруктурыCONSTANT_Long_info
и CONSTANT_Double_info
представьте числовых 8 байтов (long
и double
) константы: Все 8-байтовые константы приводят две записи в рабочее состояние в
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 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.
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).CONSTANT_Utf8_info
СтруктураCONSTANT_Utf8_info
структура используется, чтобы представить постоянные строковые значения. Строки UTF-8 кодируются так, чтобы символьные последовательности, которые содержат только ненулевые символы ASCII, могли быть представлены, используя только 1 байт за символ, но символы до 16 битов могут быть представлены. Все символы в диапазоне '\u0001'
к '\u007F'
представляются единственным байтом:
0 | биты 6-0 |
7 битов данных в байте дают значение представленного символа. Нулевой символ ('\u0000'
) и символы в диапазоне '\u0080'
к '\u07FF'
представляются парой байтов x и y:
1 | 1 | 0 | биты 10-6 |
1 | 0 | биты 5-0 |
Байты представляют символ со значением ((x & 0x1f
) << 6
) + (y & 0x3f
).
Символы в диапазоне '\u0800'
к '\uFFFF'
представляются на 3 байта x, y, и z:
1 | 1 | 1 | 0 | биты 15-12 |
1 | 0 | биты 11-6 |
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 {
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
.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).
Поля классов могут установить любой из флагов в Таблице 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).
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. Методы классов могут установить любой из флагов в Таблице 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).
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
средство чтения файлов может использовать информацию, которую они содержат, или иначе должны тихо проигнорировать те атрибуты.
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
спецификация файла.
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
|
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).
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
только описанный, или один из их подклассов. 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
outer_class_info_index
элемент должен быть нулем. Иначе, значение outer_class_info_index
элемент должен быть допустимым индексом в constant_pool
таблица, и запись по тому индексу должны быть a CONSTANT_Class_info
структура (§4.4.1), представляющая класс или интерфейсом которого C является элементом.inner_name_index
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. Все биты inner_class_access_flags
элемент, не присвоенный в Таблице 4.7, резервируется для будущего использования. Они должны быть обнулены в сгенерированном class
файлы и должны быть проигнорированы реализациями виртуальной машины Java.
InnerClasses
атрибут с любым class
на файл, фактически представляющий класс или интерфейс, ссылается атрибут.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
элемент является нулем.
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
файл был скомпилирован. Это не будет интерпретироваться как указание на имя каталога, содержащего файл или абсолютный путь для файла; такая специфичная для платформы дополнительная информация должна быть предоставлена интерпретатором времени выполнения или средством разработки в то время, когда имя файла фактически используется.
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
элемент должен дать соответствующий номер строки в файле первоисточника.
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
.
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
элемент является нулем.
code
массив Code
атрибут a method_info
структура a class
файл. Этот раздел описывает ограничения, связанные с содержанием Code_attribute
структура. class
файл - те, которые определяют отмеченность файла. За исключением статических ограничений на код виртуальной машины Java class
файл, эти ограничения были даны в предыдущем разделе. Статические ограничения на виртуальную машину Java кодируют в a class
файл определяет, как инструкции виртуальной машины Java должны быть размечены в code
массив и каковы операнды отдельных инструкций должны быть.
Статические ограничения на инструкции в code
массив следующие:
code
массив не должен быть пустым, таким образом, code_length
у элемента не может быть значения 0
.
code_length
элемент должен быть меньше чем 65536
.
code
массив начинается по индексу 0
.
code
массив. Экземпляры инструкций, используя зарезервированные коды операций (§6.2) или любые коды операций, не задокументированные в эту спецификацию, возможно, не появляются в code
массив.
code
массив кроме последнего, индекс кода операции следующей инструкции равняется индексу кода операции текущей команды плюс длина той инструкции, включая все ее операнды. Широкая инструкция обрабатывается как любая другая инструкция в этих целях; код операции, определяющий работу, которую должна изменить широкая инструкция, обрабатывается как один из операндов той широкой инструкции. Тот код операции никогда не должен быть непосредственно достижимым вычислением.
code
массив должен быть байтом по индексу code_length
-1
. code
массив следующие:
constant_pool
таблица. Операнды каждой ldc_w инструкции должны представить допустимый индекс в constant_pool
таблица. В обоих случаях постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Integer
, CONSTANT_Float
, или CONSTANT_String
.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Long
или CONSTANT_Double
. Кроме того, последующий постоянный индекс пула должен также быть допустимым индексом в постоянный пул, и постоянная запись пула по тому индексу не должна использоваться.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Fieldref
.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Methodref
.
'<'
('\u003c'
) может быть вызван инструкциями вызова метода. В частности класс или интерфейсный метод инициализации особенно называют <clinit>
никогда не вызывается явно от инструкций виртуальной машины Java, но только неявно виртуальной машиной Java непосредственно.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_InterfaceMethodref
. Значение операнда количества каждой invokeinterface инструкции должно отразить число локальных переменных, необходимых, чтобы сохранить параметры, которые передадут к интерфейсному методу, как подразумевающийся дескриптором CONSTANT_NameAndType_info
структура, на которую ссылаются CONSTANT_InterfaceMethodref
постоянная запись пула. У четвертого байта операнда каждой invokeinterface инструкции должен быть нуль значения.
constant_pool
таблица. Постоянная запись пула, на которую ссылается тот индекс, должна иметь тип CONSTANT_Class
.
CONSTANT_Class
constant_pool
запись таблицы, представляющая класс массива. Новая инструкция не может использоваться, чтобы создать массив. Новая инструкция также не может использоваться, чтобы создать экземпляр интерфейса или экземпляр abstract
класс.
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
.
max_locals
-1
. indexbyte операнды каждой широкой инструкции, изменяющей lload, dload, lstore, или dstore инструкцию, должны представить неотрицательное целое число, не больше чем max_locals
-2
. code
массив определяет ограничения на отношения между инструкциями виртуальной машины Java. Структурные ограничения следующие: int
также разрешается работать на значениях типа boolean
, byte
, char
, и short
. (Как отмечено в §3.3.4 и §3.11.1, виртуальная машина Java внутренне преобразовывает значения типов boolean
, byte
, char
, и short
вводить int
.)
long
или double
будьте инвертированы или разделенная пара. Ни в каком смысле не может локальные переменные такой пары управляться на индивидуально.
long
или double
) может быть получен доступ прежде, чем это будет присвоено значение.
max_stack
элемент.
Object
, должен вызвать любой другой метод инициализации экземпляра this
или метод инициализации экземпляра ее прямого суперкласса super
прежде, чем к его членам экземпляра получают доступ. Однако, поля экземпляра this
это объявляется в текущем классе, может быть присвоен прежде, чем вызвать любой метод инициализации экземпляра.
boolean
, byte
, char
, short
, или int
, только ireturn инструкция может использоваться. Если метод возвращает a float
, long
, или double
, только freturn, lreturn, или dreturn инструкция, соответственно, может использоваться. Если метод возвращает a reference
введите, это должно сделать так использование areturn инструкции, и тип возвращенного значения должен быть присвоением, совместимым (§2.6.7) с дескриптором возврата (§4.3.3) метода. Все методы инициализации экземпляра, класс или интерфейсные методы инициализации, и методы, которые, как объявляют, возвратились void
должен использовать только инструкцию возврата.
protected
поле суперкласса, тогда тип получаемого доступ экземпляра класса должно быть тем же самым как или подкласс текущего класса. Если invokevirtual или invokespecial привыкли к доступу a protected
метод суперкласса, тогда тип получаемого доступ экземпляра класса должен быть тем же самым как или подкласс текущего класса.
boolean
, byte
, char
, short
, или int
, тогда значение должно быть int
. Если тип дескриптора float
, long
, или double
, тогда значение должно быть a float
, long
, или double
, соответственно. Если тип дескриптора является a reference
введите, тогда значение должно иметь тип, который является присвоением, совместимым (§2.6.7) с типом дескриптора.
reference
aastore инструкцией должно быть присвоение, совместимое (§2.6.7) с компонентным типом массива.
Throwable
или подклассов Throwable
.
code
массив.
returnAddress
) может быть загружен из локальной переменной.
try
-finally
конструкции изнутри a finally
пункт. Для получения дополнительной информации по подпрограммам виртуальной машины Java см. §4.9.6.)
returnAddress
может быть возвращен к самое большее однажды. Если мочить инструкция возвращается к вопросу в цепочке вызова подпрограммы выше мочить инструкции, соответствующей приведенному примеру типа returnAddress
, тогда тот экземпляр никогда не может использоваться в качестве обратного адреса. class
Файлыclass
файлы. Браузер HotJava должен определить ли class
файл был произведен защищенным компилятором или противником, пытающимся использовать виртуальную машину. Дополнительной проблемой со временем компиляции, проверяя является скос версии. Пользователь, возможно, успешно скомпилировал класс, сказать PurchaseStockOptions
, быть подклассом TradingClass
. Но определение TradingClass
возможно, изменился со времени класс был скомпилирован в пути, который не является совместимым с существующими ранее двоичными файлами. Методы, возможно, были удалены или имели свои типы возврата или измененные модификаторы. Поля, возможно, изменили типы или изменились от переменных экземпляра до переменных класса. Модификаторы доступа метода или переменной, возможно, изменились от public
к private
. Для обсуждения этих проблем см. Главу 13, "Совместимость на уровне двоичных кодов," в первом выпуске Спецификации языка JavaTM или эквивалентной главы во втором выпуске.
Из-за этих потенциальных проблем виртуальная машина Java должна проверить для себя, что требуемые ограничения удовлетворяются class
файлы это пытается соединиться. Реализация виртуальной машины Java проверяет что каждый class
файл удовлетворяет необходимые ограничения при соединении времени (§2.17.3). Структурные ограничения на код виртуальной машины Java могут быть проверены, используя простую программу автоматического доказательства теоремы.
Разовая соединением проверка улучшает производительность интерпретатора. Могут быть устранены дорогие проверки, которые должны были бы иначе быть выполнены, чтобы проверить ограничения во время выполнения для каждой интерпретируемой инструкции. Виртуальная машина Java может предположить, что эти проверки были уже выполнены. Например, виртуальная машина Java будет уже знать следующее:
class
верификатор файла независим от любого компилятора. Это должно сертифицировать весь код, сгенерированный компилятором Sun для языка программирования Java; это должно также сертифицировать код, который другие компиляторы могут генерировать, так же как код, который не мог возможно генерировать текущий компилятор. Любой class
файл, который удовлетворяет структурные критерии и статические ограничения, будет сертифицирован верификатором.
class
верификатор файла также независим от языка программирования Java. Программы, записанные на других языках, могут быть скомпилированы в class
формат файла, но передаст проверку, только если весь одинаковый ограничения удовлетворяются.
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:
Во время соединения верификатор проверяет code
массив Code
атрибут для каждого метода class
файл, выполняя анализ потока данных каждого метода. Верификатор гарантирует, что в любой данной точке в программе, независимо от того какой путь выполнения кода берется, чтобы достигнуть той точки, следующее является истиной:
Передача 4:
По причинам эффективности задерживаются определенные тесты, которые могли в принципе быть выполнены в Передаче 3, до первого раза фактически вызывается код для метода. Таким образом, Передача 3 из верификатора избегает загружаться class
файлы, если это не имеет к.
Например, если метод вызывает другой метод, который возвращает экземпляр класса A
, и тот экземпляр присваивается только полю того же самого типа, верификатор не потрудился проверять если класс A
фактически существует. Однако, если это присваивается полю типа B
, определения обоих A
и B
должен быть загружен в гарантировать это A
подкласс B
.
Передача 4 является виртуальной передачей, проверка которой делается соответствующими инструкциями виртуальной машины Java. В первый раз инструкция, что ссылается на тип, выполняется, выполняющаяся инструкция делает следующее:
LinkageError
быть брошенным.Реализации виртуальной машины Java позволяют выполнить любую из Передачи 4 шага как часть Передачи 3; см. 2.17.1, "Запуск Виртуальной машины" для примера и большего количества обсуждения.
В одной из реализаций виртуальной машины Java Sun, после того, как была выполнена проверка, инструкция в коде виртуальной машины Java заменяется альтернативной формой инструкции. Эта альтернативная инструкция указывает, что проверка, необходимая этой инструкции, имела место и не должна быть выполнена снова. Последующие вызовы метода таким образом будут быстрее. Это недопустимо для этих альтернативных форм инструкции, чтобы появиться в class
файлы, и с ними никогда не должен встречаться верификатор.
class
проверка файла. Этот раздел смотрит на проверку кода виртуальной машины Java в Передаче 3 более подробно. Код для каждого метода проверяется независимо. Во-первых, байты, которые составляют код, разбиваются в последовательность инструкций, и индекс в code
массив запуска каждой инструкции размещается в массив. Верификатор тогда проходит через код во второй раз и анализирует инструкции. Во время этой передачи структура данных создается, чтобы содержать информацию о каждой инструкции виртуальной машины Java в методе. Операнды, если таковые вообще имеются, каждой инструкции проверяются, чтобы удостовериться, что они допустимы. Например:
code
массив для метода.
int
или float
или для экземпляров класса String
; инструкция getfield должна сослаться на поле.
byte
, short
, char
) когда определение значения вводит на стеке операнда. Затем, поток данных анализатор инициализируется. Для первой инструкции метода локальные переменные, которые представляют параметры первоначально, содержат значения типов, обозначенных дескриптором типа метода; стек операнда пуст. Все другие локальные переменные содержат недопустимое значение. Для других инструкций, которые еще не были исследованы, никакая информация не доступна относительно стека операнда или локальных переменных.
Наконец, поток данных анализатор выполняется. Для каждой инструкции "измененный" бит указывает, нужно ли на эту инструкцию смотреть. Первоначально, "измененный" бит устанавливается только для первой инструкции. Поток данных анализатор выполняет следующий цикл:
reference
значения могут появиться в соответствующих местах на двух стеках. В этом случае объединенный стек операнда содержит a reference
к экземпляру первого общего суперкласса двух типов. Такой ссылочный тип всегда существует потому что тип Object
суперкласс всего класса и интерфейсных типов. Если стеки операнда не могут быть объединены, проверка сбоев метода.
Чтобы объединить два состояния массива локальной переменной, соответствующие пары локальных переменных сравниваются. Если два типа не идентичны, то, если оба не содержат reference
значения, записи верификатора, что локальная переменная содержит неприменимое значение. Если обе из пары локальных переменных содержат reference
значения, объединенное состояние содержит a reference
к экземпляру первого общего суперкласса двух типов.
Если поток данных, анализатор работает на методе, не сообщая об отказе проверки, то метод был успешно проверен Передачей 3 из class
верификатор файла.
Определенные инструкции и типы данных усложняют поток данных анализатор. Мы теперь исследуем каждый из них более подробно.
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 должны использоваться вместо этого.
может быть реализован следующим:
...
new myClass(i, j, k);
...
Эта последовательность инструкции листы недавно создаваемый и инициализированный объект сверху стека операнда. (Дополнительные примеры компиляции к набору команд виртуальной машины Java даются в Главе 7, "Компилирующей для виртуальной машины Java.")
... new #1 // Allocate uninitialized space formyClass
dup // Duplicate object on the operand stack iload_1 // Push i iload_2 // Push j iload_3 // Push k invokespecial #5 // InvokemyClass.<init>
...
Метод инициализации экземпляра (§3.9) для класса myClass
рассматривает новый неинициализированный объект как this
параметр в локальной переменной 0
. Прежде, чем тот метод вызывает другой метод инициализации экземпляра myClass
или его прямой суперкласс на this
, единственная работа метод может выполнить на this
присваивает поля, объявленные в пределах myClass
.
Делая анализ потока данных методов экземпляра, верификатор инициализирует локальную переменную 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
конструкция, компилятор Sun для языка программирования Java использует средства обработки исключений вместе с двумя специальными инструкциями: jsr ("переходят к подпрограмме") и мочат ("возврат из подпрограммы"). finally
пункт компилируется как подпрограмма в пределах кода виртуальной машины Java для его метода, очень как код для обработчика исключений. Когда jsr инструкция, которая вызывает подпрограмму, выполняется, это продвигает свой обратный адрес, адрес инструкции после jsr, который выполняется на стек операнда как значение типа returnAddress
. Код для подпрограммы хранит обратный адрес в локальной переменной. В конце подпрограммы мочить инструкция выбирает обратный адрес от локальной переменной и передает управление инструкции в обратном адресе.
Управление может быть передано finally
пункт ( finally
подпрограмма может быть вызвана) несколькими различными способами. Если try
пункт обычно завершается, finally
подпрограмма вызывается через jsr инструкцию прежде, чем оценить следующее выражение. A break
или continue
в try
пункт, который передает управление вне try
пункт выполняет jsr к коду для finally
пункт сначала. Если try
пункт выполняет a return
, скомпилированный код делает следующее:
finally
пункт.
finally
пункт, возвращает значение, сохраненное в локальной переменной. try
пункт. Если исключение добавляется try
пункт, этот обработчик исключений делает следующее:
finally
пункт.
finally
пункт, повторно бросает исключение. try-finally
создайте, см. Раздел 7.13, "Компилируя finally
."
Код для finally
пункт представляет специальную проблему верификатору. Обычно, если определенная инструкция может быть достигнута через разнообразные пути, и определенная локальная переменная содержит несовместимые значения через те разнообразные пути, то локальная переменная становится неприменимой. Однако, a finally
пункт можно было бы вызвать от нескольких различных мест, приводя к нескольким различным обстоятельствам:
return
может иметь некоторую локальную переменную, которая содержит возвращаемое значение.
try
у пункта может быть неопределенное значение в той же самой локальной переменной. finally
сам пункт мог бы передать проверку, но после завершения обновления всех преемников мочить инструкции, верификатор отметит, что локальная переменная, что обработчик исключений ожидает содержать исключение, или что код возврата ожидает содержать возвращаемое значение, теперь содержит неопределенное значение.
Проверка кода, который содержит a finally
пункт усложняется. Основная идея является следующим:
finally
пункт, это имеет длину один. Для умножаются вложенный finally
код (чрезвычайно редкий!), это может быть более длинно чем один.
class
формат файла: constant_pool_count
поле ClassFile
структура (§4.1). Это действует как внутренний предел на полной сложности единого класса или интерфейса.
native
, не -abstract
метод ограничивается 65536 байтами размерами индексов в exception_table
из Code
атрибут (§4.7.3), в LineNumberTable
атрибут (§4.7.8), и в LocalVariableTable
атрибут (§4.7.9).
max_locals
элемент Code
атрибут (§4.7.3) предоставление кода метода. Отметьте это значения типа long
и double
как каждый полагают, резервируют две локальных переменные и вносят два модуля к max_locals
значение, таким образом, использование локальных переменных тех типов далее уменьшает этот предел.
fields_count
элемент ClassFile
структура (§4.1). Отметьте что значение fields_count
элемент ClassFile
структура не включает поля, которые наследованы от суперклассов или суперинтерфейсов.
methods_count
элемент ClassFile
структура (§4.1). Отметьте что значение methods_count
элемент ClassFile
структура не включает методы, которые наследованы от суперклассов или суперинтерфейсов.
interfaces_count
элемент ClassFile
структура (§4.1).
max_stack
поле Code_attribute
структура (§4.7.3). Отметьте это значения типа long
и double
как каждый полагают, вносят два модуля к max_stack
значение, таким образом, использование значений этих типов на операнде складывают далее, уменьшает этот предел.
max_locals
поле Code_attribute
структура (§4.7.3) и 16-разрядная индексация локальной переменной набора команд виртуальной машины Java.
this
в случае экземпляра или интерфейсных вызовов метода. Отметьте, что дескриптор метода определяется с точки зрения понятия длины параметра метода в который параметр типа long
или double
вносит два модуля длине, таким образом, параметры этих типов далее уменьшают предел.
length
элемент CONSTANT_Utf8_info
структура (§4.4.7). Отметьте, что предел находится на числе байтов в кодировании а не на числе закодированных символов. UTF-8 кодирует некоторые символы, используя два или три байта. Таким образом строки, включающие многобайтовые символы, далее ограничиваются. 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