Spec-Zone .ru
спецификации, руководства, описания, API
 Платформа Java™
Стандарт Эд. 7

Пакет java.lang.invoke

java.lang.invoke пакет содержит динамическую поддержку языка, оказанную непосредственно библиотеками классов ядра Java и виртуальной машиной.

См.: Описание

Пакет java.lang.invoke Описание

java.lang.invoke пакет содержит динамическую поддержку языка, оказанную непосредственно библиотеками классов ядра Java и виртуальной машиной.

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

Сводка соответствующих изменений виртуальной машины Java

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

invokedynamic инструкции

Динамический сайт вызова находится первоначально в расцепляемом состоянии. В этом состоянии нет никакого целевого метода для сайта вызова, чтобы вызвать.

Прежде, чем JVM может выполнить динамический сайт вызова ( invokedynamic инструкция), сайт вызова должен сначала быть соединен. Соединение выполняется, вызывая метод начальной загрузки, которому дают статический информационный контент сайта вызова, и который должен произвести a method handle это дает поведение сайта вызова.

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

Соединение запускается с разрешения постоянной записи пула для метода начальной загрузки, и разрешения a MethodType объект для дескриптора типа динамического сайта вызова. Этот процесс разрешения может инициировать загрузку класса. Это может поэтому бросить ошибку, если класс не в состоянии загрузиться. Эта ошибка становится аварийным завершением динамического выполнения сайта вызова. Редактирование не инициировало инициализацию класса.

Метод начальной загрузки вызывается по крайней мере на три значения:

Вызов то, как будто MethodHandle.invoke. Возвращенным результатом должен быть a CallSite (или подкласс). Тип цели сайта вызова должен быть точно равным типу, полученному из динамического дескриптора типа сайта вызова, и передал к методу начальной загрузки. Сайт вызова тогда становится постоянно соединенным с динамическим сайтом вызова.

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

синхронизация редактирования

Динамический сайт вызова соединяется как раз перед его первым выполнением. Вызов метода начальной загрузки, реализовывая редактирование происходит в пределах потока, который делает попытку первого выполнения.

Если есть несколько таких потоков, метод начальной загрузки может быть вызван в нескольких потоках одновременно. Поэтому, загрузите методы, какие глобальные данные приложения доступа должны взять обычные предосторожности против условий гонки. В любом случае, каждый invokedynamic инструкция или расцепляется или соединяется с уникальным CallSite объект.

В приложении, которое требует динамических сайтов вызова с индивидуально изменчивыми поведениями, их методы начальной загрузки должны произвести отличный CallSite объекты, один для каждого запроса редактирования. Альтернативно, приложение может соединить сингл CallSite возразите против нескольких invokedynamic инструкции, когда изменение к целевому методу станет видимым в каждой из инструкций.

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

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

типы методов начальной загрузки

Пока каждый метод начальной загрузки может быть правильно вызван MethodHandle.invoke, его подробный тип произволен. Например, первый параметр мог быть Object вместо MethodHandles.Lookup, и тип возврата мог также быть Object вместо CallSite. (Отметьте, что типы и число сложенных параметров ограничивают юридические виды методов начальной загрузки к соответственно введенным статическим методам и конструкторам CallSite подклассы.)

Если данный invokedynamic инструкция не определяет статических параметров, метод начальной загрузки инструкции будет вызван на три параметра, передавая класс вызывающей стороны инструкции, имя, и тип метода. Если invokedynamic инструкция определяет один или более статических параметров, те значения передадут как дополнительные параметры дескриптору метода. (Отметьте, что, потому что есть предел 255 параметров любому методу, самое большее 251 дополнительный параметр может быть предоставлен, так как дескриптор метода начальной загрузки непосредственно и его первые три параметра должны также быть сложены.) Метод начальной загрузки будет вызван как будто также MethodHandle.invoke или invokeWithArguments. (Нет никакого способа сказать различие.)

Нормальное преобразование параметра управляет для MethodHandle.invoke применитесь ко всем сложенным параметрам. Например, если продвинутое значение является типом примитива, оно может быть преобразовано в ссылку, упаковывая преобразование. Если метод начальной загрузки является переменным методом арности (его бит модификатора 0x0080 устанавливается), тогда некоторые или все параметры, определенные здесь, могут быть забраны в запаздывающий параметр массива. (Это не специальное правило, а скорее полезное последствие взаимодействия между CONSTANT_MethodHandle константы, бит модификатора для переменных методов арности, и asVarargsCollector преобразование.)

Учитывая эти правила, вот примеры юридических объявлений метода начальной загрузки учитывая различные числа N из дополнительных параметров. Первые строки (отмеченный *) будет работать на любое число дополнительных параметров.

Nдемонстрационный метод начальной загрузки
*CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
*CallSite bootstrap(Object... args)
*CallSite bootstrap(Object caller, Object... nameAndTypeWithArgs)
0CallSite bootstrap(Lookup caller, String name, MethodType type)
0CallSite bootstrap(Lookup caller, Object... nameAndType)
1CallSite bootstrap(Lookup caller, String name, MethodType type, Object arg)
2CallSite bootstrap(Lookup caller, String name, MethodType type, Object... args)
2CallSite bootstrap(Lookup caller, String name, MethodType type, String... args)
2CallSite bootstrap(Lookup caller, String name, MethodType type, String x, int y)
Последний пример предполагает, что дополнительные параметры имеют тип CONSTANT_String и CONSTANT_Integer, соответственно. Предпоследний пример предполагает, что все дополнительные параметры имеют тип CONSTANT_String. Другие примеры работают со всеми типами дополнительных параметров.

Как отмечено выше, фактический тип метода метода начальной загрузки может измениться. Например, четвертый параметр мог быть MethodHandle, если это - тип соответствующей константы в CONSTANT_InvokeDynamic запись. В этом случае, MethodHandle.invoke вызов передаст дополнительный дескриптор метода, постоянный как Object, но машина соответствия типа MethodHandle.invoke бросит ссылку назад на MethodHandle прежде, чем вызвать метод начальной загрузки. (Если бы строковую константу передали вместо этого, ужасно сгенерированным кодом, которые бросают, то тогда перестал бы работать, приводя к a BootstrapMethodError.)

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

С тех пор:
1.7
 Платформа Java™
Стандарт Эд. 7

Представьте ошибку или функцию
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.