Spec-Zone .ru
спецификации, руководства, описания, API
|
public static final class MethodHandles.Lookup extends Object
Поиск class, который должен создать дескрипторы метода, вызовет MethodHandles.lookup
создать фабрику для себя. Когда Lookup
объект фабрики создается, идентификационные данные поиска, class определяется, и надежно сохранен в Lookup
объект. Поиск class (или его делегаты) может тогда использовать методы фабрики на Lookup
объект создать дескрипторы метода для проверенных в доступе элементов. Это включает все методы, конструкторов, и поля, которые позволяются поиску class, даже частные.
Методы фабрики на a Lookup
объект соответствует всем главным вариантам использования для методов, конструкторов, и полей. Вот является сводка корреспонденции между этими методами фабрики и поведением получающимися дескрипторами метода:
Здесь, тип
lookup expression member behavior
lookup.findGetter (C.class, "f", Футы class)
FT f; (T) this.f;
lookup.findStaticGetter (C.class, "f", Футы class)
static
FT f;(T) C.f;
lookup.findSetter (C.class, "f", Футы class)
FT f; this.f = x;
lookup.findStaticSetter (C.class, "f", Футы class)
static
FT f;C.f = arg;
lookup.findVirtual (C.class, "м.", MT)
T m(A*); (T) this.m(arg*);
lookup.findStatic (C.class, "м.", MT)
static
T m(A*);(T) C.m(arg*);
lookup.findSpecial (C.class, "м.", MT, это. class)
T m(A*); (T) super.m(arg*);
lookup.findConstructor (C.class, Монтана)
C(A*); (T) new C(arg*);
lookup.unreflectGetter (далеко от дома)
(static)?
FT f;(FT) aField.get(thisOrNull);
lookup.unreflectSetter (далеко от дома)
(static)?
FT f;aField.set(thisOrNull, arg);
lookup.unreflect (aMethod)
(static)?
T m(A*);(T) aMethod.invoke(thisOrNull, arg*);
lookup.unreflectConstructor (aConstructor)
C(A*); (C) aConstructor.newInstance(arg*);
lookup.unreflect (aMethod)
(static)?
T m(A*);(T) aMethod.invoke(thisOrNull, arg*);
C
class или интерфейс, искавший элемент, задокументированный в качестве параметра названный refc
в методах поиска. Метод или тип конструктора MT
составляется из типа возврата T
и последовательность типов параметра A*
. Оба MT
и тип поля FT
документируются в качестве параметра названные type
. Формальный параметр this
стенды для самоссылки типа C
; если это присутствует, это всегда - ведущий параметр вызову дескриптора метода. (В случае некоторых protected
элементы, this
может быть ограничен в типе поиску class; см. ниже.) Имя arg
стенды для всех других параметров дескриптора метода. В примерах кода для Базового API Reflection, имени thisOrNull
стенды для нулевой ссылки, если метод, к которому получают доступ, или поле статичны, и this
иначе. Имена aMethod
, aField
, и aConstructor
стенд для отражающих объектов, соответствующих данным элементам.
В случаях, где данный элемент имеет переменную арность (то есть, метод или конструктор) возвращенный дескриптор метода будет также иметь переменную арность. Во всех других случаях возвращенный дескриптор метода будет иметь фиксированную арность.
Эквивалентность между смотревшими дескрипторами метода и базовыми элементами class может сломаться несколькими способами:
C
не символически доступно от загрузчика class поиска, поиск может все еще успешно выполниться, даже когда нет никакого эквивалентного выражения Java или bytecoded константы. T
или MT
не символически доступно от загрузчика class поиска, поиск может все еще успешно выполниться. Например, поиски для MethodHandle.invokeExact
и MethodHandle.invoke
будет всегда успешно выполняться, независимо от требуемого типа. ldc
инструкция не подвергается проверкам менеджера безопасности. Lookup
, когда дескриптор метода создается. Это - основное отличие от Базового API Reflection с тех пор java.lang.reflect.Method.invoke
выполняет проверку доступа против каждой вызывающей стороны, на каждом вызове. Все проверки прав доступа запускаются с a Lookup
объект, который сравнивает его записанный поиск class со всеми запросами, чтобы создать дескрипторы метода. Сингл Lookup
объект может использоваться, чтобы создать любое число проверенных в доступе дескрипторов метода, все проверенные по единственному поиску class.
A Lookup
объект может быть совместно использован с другим доверяемым кодом, таким как протокол метаобъекта. Совместно используемое Lookup
возразите делегирует возможность создать дескрипторы метода на членах парламента, не занимающих официального поста поиска class. Даже если привилегированный код использует Lookup
объект, проверка доступа ограничивается полномочиями исходного поиска class.
Поиск может перестать работать, потому что содержание class не доступно для поиска class, или потому что требуемый элемент class отсутствует, или потому что требуемый элемент class не доступен для поиска class. В любом из этих случаев, a ReflectiveOperationException
будет брошен от предпринятого поиска. Точный class будет одним из следующего:
Вообще, условия, при которых дескриптор метода может искаться метод M
точно эквивалентны условиям, при которых поиск class, возможно, скомпилировал и разрешил звонок M
. И эффект вызова дескриптора метода, следующего из поиска, точно эквивалентен выполнению скомпилированного и разрешенного звонка M
. Та же самая точка верна для полей и конструкторов.
Если требуемый элемент protected
, обычные правила JVM применяются, включая требование, чтобы поиск class был или быть в том же самом пакете как требуемый элемент, или должен наследовать тот элемент. (См. Спецификацию виртуальной машины Java, разделы 4.9.2, 5.4.3.5, и 6.4.), Кроме того, если требуемый элемент является нестатическим полем или методом в различном пакете, получающийся дескриптор метода может только быть применен к объектам поиска class или один из его подклассов. Это требование осуществляется, сужая тип продвижения this
параметр от C
(который обязательно будет суперклассом поиска class) к поиску class непосредственно.
В некоторых случаях доступ между вложенными классами получается компилятором Java, создавая метод обертки, чтобы получить доступ к закрытому методу другого class в том же самом высокоуровневом объявлении. Например, вложенный class C.D
может получить доступ к членам парламента, не занимающим официального поста в пределах других связанных классов такой как C
, C.D.E
, или C.B
, но компилятор Java, возможно, должен генерировать методы обертки в тех связанных классах. В таких случаях, a Lookup
объект на C.E
было бы неспособно тем членам парламента, не занимающим официального поста. Обходное решение для этого ограничения Lookup.in
метод, который может преобразовать поиск на C.E
в одного на любом из тех других классов, без специального повышения полномочия.
Хотя инструкции байт-кода могут только обратиться к классам в связанном загрузчике class, этот API может искать методы в любом class пока ссылка на Class
объект доступен. Такие ссылки перекрестного загрузчика также возможны с Базовым API Reflection, и невозможны к инструкциям байт-кода такой как invokestatic
или getfield
. Есть API менеджера безопасности, чтобы позволить приложениям проверять такие ссылки перекрестного загрузчика. Эти проверки применяются к обоим MethodHandles.Lookup
API и Базовый API Reflection (как найдено на Class
).
Проверки прав доступа только применяются к именованным и отраженным методам, конструкторам, и полям. Другие методы создания дескриптора метода, такой как MethodHandle.asType
, не требуйте никаких проверок прав доступа, и делаются со статическими методами MethodHandles
, независимо от любого Lookup
объект.
SecurityException
. Определить smgr
как менеджер безопасности, refc
как содержание class, в котором элемент разыскивается, и defc
как class, в котором фактически определяется элемент. Вызовы выполняются согласно следующим правилам: smgr.checkMemberAccess(refc, Member.PUBLIC)
вызывается. refc
, тогда smgr.checkPackageAccess(refcPkg)
вызывается, где refcPkg
пакет refc
. smgr.checkMemberAccess(defc, Member.DECLARED)
вызывается. (Отметьте это defc
могло бы быть то же самое как refc
.) Реализация по умолчанию этого метода менеджера безопасности осматривает стек, чтобы определить исходную вызывающую сторону отражающего запроса (такой как findStatic
), и выполняет дополнительные проверки разрешения если загрузчик class defc
отличается от загрузчика class class, из которого прибыл отражающий запрос. defc
и refc
находятся в различных загрузчиках class, и если загрузчик class поиска class не является тем же самым как или предок загрузчика class defc
, тогда smgr.checkPackageAccess(defcPkg)
вызывается, где defcPkg
пакет defc
. Модификатор и Тип | Поле и Описание |
---|---|
static int |
ПАКЕТ
Одно-разрядное представление маски
package доступ (доступ значения по умолчанию), который может способствовать результату lookupModes . |
static int |
ЧАСТНЫЙ
Одно-разрядное представление маски
private доступ, который может способствовать результату lookupModes . |
static int |
ЗАЩИЩЕННЫЙ
Одно-разрядное представление маски
protected доступ, который может способствовать результату lookupModes . |
static int |
ОБЩЕСТВЕННОСТЬ
Одно-разрядное представление маски
public доступ, который может способствовать результату lookupModes . |
Модификатор и Тип | Метод и Описание |
---|---|
MethodHandle |
bind(Object receiver, String name, MethodType type)
Производит ранне-ограниченный дескриптор метода для нестатического метода.
|
MethodHandle |
findConstructor(Class<?> refc, MethodType type)
Производит дескриптор метода, который создает объект и инициализирует его, используя конструктора указанного типа.
|
MethodHandle |
findGetter(Class<?> refc, String name, Class<?> type)
Производит дескриптор метода, дающий доступ для чтения к нестатическому полю.
|
MethodHandle |
findSetter(Class<?> refc, String name, Class<?> type)
Производит дескриптор метода, дающий доступ для записи к нестатическому полю.
|
MethodHandle |
findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller)
Производит ранне-ограниченный дескриптор метода для виртуального метода, как будто вызванный от
invokespecial инструкция от caller . |
MethodHandle |
findStatic(Class<?> refc, String name, MethodType type)
Производит дескриптор метода для статического метода.
|
MethodHandle |
findStaticGetter(Class<?> refc, String name, Class<?> type)
Производит дескриптор метода, дающий доступ для чтения к статическому полю.
|
MethodHandle |
findStaticSetter(Class<?> refc, String name, Class<?> type)
Производит дескриптор метода, дающий доступ для записи к статическому полю.
|
MethodHandle |
findVirtual(Class<?> refc, String name, MethodType type)
Производит дескриптор метода для виртуального метода.
|
MethodHandles. Поиск |
in(Class<?> requestedLookupClass)
Создает поиск на указанном новом поиске class.
|
Class<?> |
lookupClass()
Говорит, который class выполняет поиск.
|
int |
lookupModes()
Говорит, какие классы защиты доступа элементов этот объект поиска может произвести.
|
Строка |
toString()
Выводит на экран имя class, из которого должны быть сделаны поиски.
|
MethodHandle |
unreflect(Method m)
Делает дескриптор прямого метода к м., если у поиска class есть разрешение.
|
MethodHandle |
unreflectConstructor(Constructor c)
Производит дескриптор метода для отраженного конструктора.
|
MethodHandle |
unreflectGetter(Field f)
Производит дескриптор метода, дающий доступ для чтения к отраженному полю.
|
MethodHandle |
unreflectSetter(Field f)
Производит дескриптор метода, дающий доступ для записи к отраженному полю.
|
MethodHandle |
unreflectSpecial(Method m, Class<?> specialCaller)
Производит дескриптор метода для отраженного метода.
|
public static final int PUBLIC
public
доступ, который может способствовать результату lookupModes
. Значение, 0x01
, оказывается, то же самое как значение public
бит модификатора.public static final int PRIVATE
private
доступ, который может способствовать результату lookupModes
. Значение, 0x02
, оказывается, то же самое как значение private
бит модификатора.public static final int PROTECTED
protected
доступ, который может способствовать результату lookupModes
. Значение, 0x04
, оказывается, то же самое как значение protected
бит модификатора.public static final int PACKAGE
package
доступ (доступ значения по умолчанию), который может способствовать результату lookupModes
. Значение 0x08
, который не соответствует обоснованно никакому определенному биту модификатора.public Class<?> lookupClass()
class подразумевает максимальный уровень права доступа, но полномочия могут быть дополнительно ограничены битовой маской lookupModes
, который управляет, можно ли к непубличным элементам получить доступ.
public int lookupModes()
У недавно создаваемого объекта поиска на class вызывающей стороны есть весь возможный набор битов, начиная с вызывающей стороны, class может получить доступ ко всем своим собственным элементам. У объекта поиска на новом поиске class, создаваемый из предыдущего объекта поиска, могут быть некоторые обнуленные биты режима. Цель этого состоит в том, чтобы ограничить доступ через новый объект поиска, так, чтобы это могло получить доступ только к именам, которые могут быть достигнуты исходным объектом поиска, и также новым поиском class.
public MethodHandles.Lookup in(Class<?> requestedLookupClass)
lookupClass
. Однако, получающееся Lookup
у объекта, как гарантируют, больше не будет возможностей доступа чем оригинал. В частности возможности доступа могут быть потеряны следующим образом:
requestedLookupClass
- требуемый поиск class для нового объекта поискаNullPointerException
- если параметром является нульpublic String toString()
Class.getName
.), Если есть ограничения на доступ, разрешенный к этому поиску, это обозначается, добавляя суффикс к имени class, состоя из наклонной черты и ключевого слова. Ключевое слово представляет самый сильный предоставленный доступ, и выбирается следующим образом: MethodHandles.lookup
. Объекты, создаваемые Lookup.in
всегда имейте ограниченный доступ, и выведет на экран суффикс. (Может казаться странным, что защищенный доступ должен быть более сильным чем частный доступ. Просматриваемый независимо от доступа пакета, защищенный доступ является первым, чтобы быть потерянным, потому что это требует прямого отношения подкласса между вызывающей стороной и вызываемым.)
toString
в class Object
in(java.lang.Class<?>)
public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
findVirtual
или findSpecial
.) Метод и все его типы параметра должны быть доступными для поиска class. Если class метода еще не был инициализирован, который сразу делается, прежде, чем дескриптор метода возвращается. У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается.
refc
- class, от которого получают доступ к методуname
- имя методаtype
- тип методаNoSuchMethodException
- если метод не существуетIllegalAccessException
- если проверка доступа перестала работать, или если метод не static
, или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиSecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
refc
) предварительно ожидаемый. Метод и все его типы параметра должны быть доступными для поиска class. Когда вызвано, дескриптор обработает первый параметр как получатель и диспетчеризирует на типе получателя, чтобы определить который реализация метода войти. (Действие диспетчеризации идентично с выполняемым invokevirtual
или invokeinterface
инструкция.)
Первый параметр будет иметь тип refc
если у поиска class есть полные полномочия получить доступ к элементу. Иначе элемент должен быть protected
и первый параметр будет ограничен в типе поиску class.
У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается.
Из-за общей эквивалентности между invokevirtual
инструкции и дескрипторы метода, произведенные findVirtual
, если class MethodHandle
и строка имени invokeExact
или invoke
, получающийся дескриптор метода эквивалентен одному произведенному MethodHandles.exactInvoker
или MethodHandles.invoker
с тем же самым type
параметр.
refc
- class или интерфейс, от которого получают доступ к методуname
- имя методаtype
- тип метода, с опущенным параметром получателяNoSuchMethodException
- если метод не существуетIllegalAccessException
- если проверка доступа перестала работать, или если метод static
или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиSecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException
Отметьте: У требуемого типа должен быть тип возврата void
. Это является непротиворечивым с обработкой JVM дескрипторов типа конструктора.
У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности конструктора (0x0080
) устанавливается.
refc
- class или интерфейс, от которого получают доступ к методуtype
- тип метода, с параметром получателя, опущенным, и пустой тип возвратаNoSuchMethodException
- если конструктор не существуетIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиSecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException
invokespecial
инструкция от caller
. Тип дескриптора метода будет типом метода с соответственно ограниченным типом получателя (такой как caller
) предварительно ожидаемый. Метод и все его типы параметра должны быть доступными для вызывающей стороны. Когда вызвано, дескриптор обработает первый параметр как получатель, но не будет диспетчеризировать на типе получателя. (Это прямое действие вызова идентично с выполняемым invokespecial
инструкция.)
Если явно указанная вызывающая сторона, class не идентичен с поиском class, или если у этого объекта поиска нет частных прав доступа, сбоев доступа.
У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается.
refc
- class или интерфейс, от которого получают доступ к методуname
- имя метода (который не должен быть" <init>"),type
- тип метода, с опущенным параметром получателяspecialCaller
- предложенный вызов class, чтобы выполнить invokespecial
NoSuchMethodException
- если метод не существуетIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиSecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- class или интерфейс, от которого получают доступ к методуname
- имя поляtype
- тип поляNoSuchFieldException
- если поле не существуетIllegalAccessException
- если проверка доступа перестала работать, или если поле static
SecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- class или интерфейс, от которого получают доступ к методуname
- имя поляtype
- тип поляNoSuchFieldException
- если поле не существуетIllegalAccessException
- если проверка доступа перестала работать, или если поле static
SecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- class или интерфейс, от которого получают доступ к методуname
- имя поляtype
- тип поляNoSuchFieldException
- если поле не существуетIllegalAccessException
- если проверка доступа перестала работать, или если поле не static
SecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException
refc
- class или интерфейс, от которого получают доступ к методуname
- имя поляtype
- тип поляNoSuchFieldException
- если поле не существуетIllegalAccessException
- если проверка доступа перестала работать, или если поле не static
SecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException
defc
в котором метод имени и типа доступен для поиска class. Метод и все его типы параметра должны быть доступными для поиска class. Тип дескриптора метода будет типом метода без любой вставки дополнительного параметра получателя. Данный получатель будет связан в дескриптор метода, так, чтобы каждый звонок в дескриптор метода вызвал требуемый метод на данный получатель. У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается и запаздывающим параметром массива не является единственный параметр. (Если запаздывающим параметром массива будет единственный параметр, то данное значение получателя будет связано с этим.)
Это эквивалентно следующему коду:
гдеimport static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle mh0 = lookup().findVirtual
(defc, name, type); MethodHandle mh1 = mh0.bindTo
(receiver); MethodType mt1 = mh1.type(); if (mh0.isVarargsCollector()) mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1)); return mh1;
defc
также receiver.getClass()
или тип высшего качества что class, в котором требуемый метод доступен для поиска class. (Отметьте это bindTo
не сохраняет переменную арность.)receiver
- объект, от которого получают доступ к методуname
- имя методаtype
- тип метода, с опущенным параметром получателяNoSuchMethodException
- если метод не существуетIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиSecurityException
- если менеджер безопасности присутствует и это отказывает в доступеNullPointerException
- если каким-либо параметром является нульpublic MethodHandle unreflect(Method m) throws IllegalAccessException
accessible
флаг не устанавливается, проверка доступа сразу выполняется от имени поиска class. Если м. не общедоступен, не совместно используйте получающийся дескриптор с недоверяемыми сторонами. У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается.
m
- отраженный методIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиNullPointerException
- если параметром является нульpublic MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException
invokespecial
инструкция изнутри specialCaller
. Тип дескриптора метода будет типом метода со специальным предварительно ожидаемым типом вызывающей стороны (а не получатель метода). Если метод accessible
флаг не устанавливается, проверка доступа сразу выполняется от имени поиска class, как будто invokespecial
инструкция соединялась. У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности метода (0x0080
) устанавливается.
m
- отраженный методspecialCaller
- class, номинально вызывая методIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиNullPointerException
- если каким-либо параметром является нульpublic MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException
newInstance
работа, создавая новый экземпляр class конструктора на параметрах, которые передают к дескриптору метода. Если конструктор accessible
флаг не устанавливается, проверка доступа сразу выполняется от имени поиска class.
У возвращенного дескриптора метода будет переменная арность если и только если переменный бит модификатора арности конструктора (0x0080
) устанавливается.
c
- отраженный конструкторIllegalAccessException
- если проверка доступа перестала работать или если переменный бит модификатора арности метода устанавливается и asVarargsCollector
сбоиNullPointerException
- если параметром является нульpublic MethodHandle unreflectGetter(Field f) throws IllegalAccessException
accessible
флаг не устанавливается, проверка доступа сразу выполняется от имени поиска class.f
- отраженное полеIllegalAccessException
- если проверка доступа перестала работатьNullPointerException
- если параметром является нульpublic MethodHandle unreflectSetter(Field f) throws IllegalAccessException
accessible
флаг не устанавливается, проверка доступа сразу выполняется от имени поиска class.f
- отраженное полеIllegalAccessException
- если проверка доступа перестала работатьNullPointerException
- если параметром является нуль
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2013, Oracle и/или его филиалы. Все права защищены.
Проект сборка-b92