Spec-Zone .ru
спецификации, руководства, описания, API
|
public class MethodHandles extends Object
Модификатор и Тип | Класс и Описание |
---|---|
static class |
MethodHandles. Поиск
Объект поиска является фабрикой для того, чтобы создать дескрипторы метода, когда создание требует проверки доступа.
|
Модификатор и Тип | Метод и Описание |
---|---|
static MethodHandle |
arrayElementGetter(Class<?> arrayClass)
Производит дескриптор метода, дающий доступ для чтения к элементам массива.
|
static MethodHandle |
arrayElementSetter(Class<?> arrayClass)
Производит дескриптор метода, дающий доступ для записи к элементам массива.
|
static MethodHandle |
catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler)
Делает дескриптор метода, который адаптирует целевой дескриптор метода, выполняя это в обработчике исключений.
|
static MethodHandle |
constant(Class<?> type, Object value)
Производит дескриптор метода требуемого типа возврата, который возвращает данную постоянную величину каждый раз, когда это вызывается.
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)
Производит дескриптор метода, который отбросит некоторые фиктивные параметры прежде, чем вызвать некоторый другой указанный целевой дескриптор метода.
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes)
Производит дескриптор метода, который отбросит некоторые фиктивные параметры прежде, чем вызвать некоторый другой указанный целевой дескриптор метода.
|
static MethodHandle |
exactInvoker(MethodType type)
Производит специальный invoker дескриптор метода, который может использоваться, чтобы вызвать любой дескриптор метода данного типа, как будто
invokeExact . |
static MethodHandle |
explicitCastArguments(MethodHandle target, MethodType newType)
Производит дескриптор метода, который адаптирует тип данного дескриптора метода к новому типу попарным параметром и преобразованием типов возврата.
|
static MethodHandle |
filterArguments(MethodHandle target, int pos, MethodHandle... filters)
Адаптирует целевой дескриптор метода, предварительно обрабатывая один или больше его параметров, каждый с его собственной унарной функцией фильтра, и затем вызывая цель с каждым предварительно обработанным параметром, замененным результатом его соответствующей функции фильтра.
|
static MethodHandle |
filterReturnValue(MethodHandle target, MethodHandle filter)
Адаптирует целевой дескриптор метода последующей обработкой его возвращаемое значение (если любой) с фильтром (другой дескриптор метода).
|
static MethodHandle |
foldArguments(MethodHandle target, MethodHandle combiner)
Адаптирует целевой дескриптор метода, предварительно обрабатывая некоторые из его параметров, и затем вызывая цель с результатом предварительной обработки, вставленной в исходную последовательность параметров.
|
static MethodHandle |
guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)
Делает дескриптор метода, который адаптирует целевой дескриптор метода, охраняя это с тестом, булевым образом оцененным дескриптором метода.
|
static MethodHandle |
identity(Class<?> type)
Производит дескриптор метода, который возвращает собственный параметр когда вызвано.
|
static MethodHandle |
insertArguments(MethodHandle target, int pos, Object... values)
Предоставляет целевому дескриптору метода один или более связанные параметры перед вызовом дескриптора метода.
|
static MethodHandle |
invoker(MethodType type)
Производит специальный invoker дескриптор метода, который может использоваться, чтобы вызвать любой дескриптор метода, совместимый с данным типом, как будто
invoke . |
static MethodHandles.Lookup |
lookup()
Возвраты a
lookup object на вызывающей стороне, у которой есть возможность получить доступ к любому дескриптору метода, что у вызывающей стороны есть доступ к, включая дескрипторы прямого метода к частным полям и методам. |
static MethodHandle |
permuteArguments(MethodHandle target, MethodType newType, int... reorder)
Производит дескриптор метода, который адаптирует вызывающую последовательность данного дескриптора метода к новому типу, переупорядочивая параметры.
|
static MethodHandles.Lookup |
publicLookup()
Возвраты a
lookup object которому доверяют минимально. |
static MethodHandle |
spreadInvoker(MethodType type, int leadingArgCount)
Производит дескриптор метода, который вызовет любой дескриптор метода данного
type , с данным числом запаздывающих параметров, замененных единственным запаздыванием Object[] массив. |
static MethodHandle |
throwException(Class<?> returnType, Class<? extends Throwable> exType)
Производит дескриптор метода, который выдаст исключения данного
exType . |
public static MethodHandles.Lookup lookup()
lookup object
на вызывающей стороне, у которой есть возможность получить доступ к любому дескриптору метода, что у вызывающей стороны есть доступ к, включая дескрипторы прямого метода к частным полям и методам. Этот объект поиска является возможностью, которая может быть делегирована к доверяемым агентам. Не храните это на месте, где недоверяемый код может получить доступ к этому.public static MethodHandles.Lookup publicLookup()
lookup object
которому доверяют минимально. Это может только использоваться, чтобы создать дескрипторы метода к публично доступным полям и методам. Как чистое соглашение, поиск class этого объекта поиска будет Object
.
Поиск class может быть изменен на любой другой class C
использование выражения формы publicLookup().in(C.class)
. Так как у всех классов есть равный доступ к общедоступным именам, такое изменение не присудило бы новых прав доступа.
public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException
int
.arrayClass
- тип массиваNullPointerException
- если параметром является нульIllegalArgumentException
- если arrayClass не является типом массиваpublic static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException
NullPointerException
- если параметром является нульIllegalArgumentException
- если arrayClass не является типом массиваpublic static MethodHandle spreadInvoker(MethodType type, int leadingArgCount)
type
, с данным числом запаздывающих параметров, замененных единственным запаздыванием Object[]
массив. Получающийся invoker будет дескриптором метода со следующими параметрами: MethodHandle
цель leadingArgCount
) Object[]
массив, содержащий запаздывание параметров invoker вызовет свою цель как звонок invoke
с обозначенным type
. Таким образом, если цель имеет точно данный type
, это будет вести себя как invokeExact
; иначе это ведет себя как будто asType
используется, чтобы преобразовать цель в необходимое type
.
Тип возвращенного invoker не будет данным type
, а скорее будет иметь все параметры кроме первого leadingArgCount
замененный единственным массивом типа Object[]
, который будет заключительным параметром.
Прежде, чем вызвать его цель, invoker распространит заключительный массив, применит ссылочные броски по мере необходимости, и распакует и расширит примитивные параметры.
Этот метод эквивалентен следующему коду (хотя это может быть более эффективно):
MethodHandle invoker = MethodHandles.invoker(type); int spreadArgCount = type.parameterCount() - leadingArgCount; invoker = invoker.asSpreader(Object[].class, spreadArgCount); return invoker;
Этот метод не выдает отражающих исключений или исключений безопасности.
type
- требуемый целевой типleadingArgCount
- число фиксированных параметров, чтобы быть переданным неизменный к целиNullPointerException
- если type
нульIllegalArgumentException
- если leadingArgCount
не находится в диапазоне от 0 до type.parameterCount()
включительноpublic static MethodHandle exactInvoker(MethodType type)
invokeExact
. У получающегося invoker будет тип, который точно равен требуемому типу, за исключением того, что это примет дополнительный ведущий параметр типа MethodHandle
. Этот метод эквивалентен следующему коду (хотя это может быть более эффективно):
publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
Обсуждение: дескрипторы метода Invoker могут быть полезными, работая с переменными дескрипторами метода неизвестных типов. Например, чтобы эмулировать invokeExact
призовите к переменному дескриптору метода M
, извлеките его тип T
, ищите invoker метод X
для T
, и вызовите invoker метод, как X.invoke(T, A...)
. (Это не работало бы, чтобы вызвать X.invokeExact
, начиная с типа T
неизвестно.), Если распространение, собираясь, или другие преобразования параметра требуется, они могут быть применены однажды к invoker X
и снова использованный на многих M
значения дескриптора метода, пока они являются совместимыми с типом X
.
(Отметьте: invoker метод не доступен через Базовый API Reflection. Попытка вызвать java.lang.reflect. Method.invoke на объявленном invokeExact
или invoke
метод повысит UnsupportedOperationException
.)
Этот метод не выдает отражающих исключений или исключений безопасности.
type
- требуемый целевой типpublic static MethodHandle invoker(MethodType type)
invoke
. У получающегося invoker будет тип, который точно равен требуемому типу, за исключением того, что это примет дополнительный ведущий параметр типа MethodHandle
. Прежде, чем вызвать ее цель, если цель отличается от ожидаемого типа, invoker применит ссылочные броски по мере необходимости и поле, распакует, или расширит примитивные значения, как будто asType
. Точно так же возвращаемое значение будет преобразовано по мере необходимости. Если цель будет переменным дескриптором метода арности, то необходимое преобразование арности будет сделано, снова как будто asType
.
Общий тип метода, упоминает только Object
параметры и возвращаемые значения. invoker для такого типа способен к вызову любого дескриптора метода той же самой арности как общий тип.
Этот метод эквивалентен следующему коду (хотя это может быть более эффективно):
publicLookup().findVirtual(MethodHandle.class, "invoke", type)
Этот метод не выдает отражающих исключений или исключений безопасности.
type
- требуемый целевой типpublic static MethodHandle explicitCastArguments(MethodHandle target, MethodType newType)
Если исходный тип и новый тип равны, цель возвратов.
Что касается тех же самых преобразований позволяют MethodHandle.asType
, и некоторые дополнительные преобразования также применяются, если те преобразования перестали работать. Данный типы T0, T1, одно из следующих преобразований применяется если возможный, прежде или вместо любых преобразований, сделанных asType
:
(x & 1) != 0
. target
- дескриптор метода, чтобы вызвать после параметров перепечатываетсяnewType
- ожидаемый тип нового дескриптора методаNullPointerException
- если любым параметром является нульWrongMethodTypeException
- если преобразование не может быть сделаноMethodHandle.asType(java.lang.invoke.MethodType)
public static MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder)
Данный массив управляет переупорядочением. Вызвать #I
число входящих параметров (значение newType.parameterCount()
, и вызовите #O
число исходящих параметров (значение target.type().parameterCount()
). Затем длина массива переупорядочения должна быть #O
, и каждый элемент должен быть неотрицательным числом меньше чем #I
. Для каждого N
меньше чем #O
, N
-th исходящий параметр будет взят от I
-th входящий параметр, где I
reorder[N]
.
Никакое значение аргумента или преобразования возвращаемого значения не применяются. Тип каждого входящего параметра, как определено newType
, должно быть идентичным типу соответствующего исходящего параметра или параметров в целевом дескрипторе метода. Тип возврата newType
должно быть идентичным типу возврата исходной цели.
Массив переупорядочения не должен определить фактическую перестановку. Входящий параметр будет дублирован, если индексировать появится не раз в массиве, и входящий параметр будет отброшен, если индексировать не появится в массиве. Как в случае dropArguments
, входящие параметры, которые не упоминаются в массиве переупорядочения, может быть любой тип, как определено только newType
.
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodType intfn1 = methodType(int.class, int.class); MethodType intfn2 = methodType(int.class, int.class, int.class); MethodHandle sub = ... {int x, int y => x-y} ...; assert(sub.type().equals(intfn2)); MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1); MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0); assert((int)rsub.invokeExact(1, 100) == 99); MethodHandle add = ... {int x, int y => x+y} ...; assert(add.type().equals(intfn2)); MethodHandle twice = permuteArguments(add, intfn1, 0, 0); assert(twice.type().equals(intfn1)); assert((int)twice.invokeExact(21) == 42);
target
- дескриптор метода, чтобы вызвать после параметров переупорядочиваетсяnewType
- ожидаемый тип нового дескриптора методаreorder
- индексировать массив, который управляет переупорядочениемNullPointerException
- если каким-либо параметром является нульIllegalArgumentException
- если индексировать длина массива не равна арности цели, или если кто-либо индексирует элемент массива не, допустимое индексирует для параметра newType
, или если два соответствующих параметра вводят target.type()
и newType
не идентичны,public static MethodHandle constant(Class<?> type, Object value)
Прежде, чем дескриптор метода возвращается, переданный - в значении преобразовывается в требуемый тип. Если требуемый тип примитивен, расширяющиеся примитивные преобразования предпринимаются, еще ссылочные преобразования предпринимаются.
Возвращенный дескриптор метода эквивалентен identity(type).bindTo(value)
.
type
- тип возврата требуемого дескриптора методаvalue
- значение, чтобы возвратитьсяNullPointerException
- если type
параметром является нульClassCastException
- если значение не может быть преобразовано в необходимый тип возвратаIllegalArgumentException
- если данный тип void.class
public static MethodHandle identity(Class<?> type)
type
- тип единственного параметра и возвращаемое значение требуемого дескриптора методаNullPointerException
- если параметром является нульIllegalArgumentException
- если данный тип void.class
public static MethodHandle insertArguments(MethodHandle target, int pos, Object... values)
Тип нового дескриптора метода отбросит типы для связанных параметров от исходного целевого типа, так как новый дескриптор метода больше не будет требовать, чтобы те параметры были предоставлены его вызывающими сторонами.
Каждый данный объект параметра должен соответствовать соответствующий связанный тип параметра. Если связанный тип параметра является примитивом, объект параметра должен быть оберткой, и будет распакован, чтобы произвести примитивное значение.
pos
параметр выбирает, какие параметры должны быть связаны. Это может расположиться между нулем и N-L (включительно), где N является арностью целевого дескриптора метода, и L является длиной массива значений.
target
- дескриптор метода, чтобы вызвать после параметра вставляетсяpos
- где вставить параметр (обнулите для первого),values
- серия параметров, чтобы вставитьNullPointerException
- если цель или values
массив является нулемMethodHandle.bindTo(java.lang.Object)
public static MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes)
pos
параметр может расположиться между нулем и N, где N является арностью цели. Если pos
нуль, фиктивные параметры будут предшествовать реальным параметрам цели; если pos
N, они прибудут после.
Пример:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class); MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2)); assertEquals(bigType, d0.type()); assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
Этот метод также эквивалентен следующему коду:
dropArguments
(target, pos, valueTypes.toArray(new Class[0]))
target
- дескриптор метода, чтобы вызвать после параметров отбрасываетсяvalueTypes
- тип (ы) параметра (ов) отбрасываниюpos
- позиция первого параметра отбрасыванию (обнуляют для крайнего левого),NullPointerException
- если цель является нулем, или если valueTypes
список или любой из его элементов являются нулемIllegalArgumentException
- если любой элемент valueTypes
void.class
, или если pos
отрицательно или больше чем арность цели, или если бы у нового типа дескриптора метода было бы слишком много параметровpublic static MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)
pos
параметр может расположиться между нулем и N, где N является арностью цели. Если pos
нуль, фиктивные параметры будут предшествовать реальным параметрам цели; если pos
N, они прибудут после.
Пример:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodHandle d0 = dropArguments(cat, 0, String.class); assertEquals("yz", (String) d0.invokeExact("x", "y", "z")); MethodHandle d1 = dropArguments(cat, 1, String.class); assertEquals("xz", (String) d1.invokeExact("x", "y", "z")); MethodHandle d2 = dropArguments(cat, 2, String.class); assertEquals("xy", (String) d2.invokeExact("x", "y", "z")); MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class); assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
Этот метод также эквивалентен следующему коду:
dropArguments
(target, pos, Arrays.asList(valueTypes))
target
- дескриптор метода, чтобы вызвать после параметров отбрасываетсяvalueTypes
- тип (ы) параметра (ов) отбрасываниюpos
- позиция первого параметра отбрасыванию (обнуляют для крайнего левого),NullPointerException
- если цель является нулем, или если valueTypes
массив или любой из его элементов являются нулемIllegalArgumentException
- если любой элемент valueTypes
void.class
, или если pos
отрицательно или больше чем арность цели, или если бы у нового типа дескриптора метода было бы слишком много параметровpublic static MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters)
Предварительная обработка выполняется одним или более дескрипторами метода, определенными в элементах filters
массив. Первый элемент массива фильтра соответствует pos
параметр цели, и так далее в последовательности.
Нулевые параметры в массиве обрабатываются как тождественные отображения, и соответствующие параметры, оставленные неизменными. (Если нет никаких ненулевых элементов в массиве, исходная цель возвращается.) Каждый фильтр применяется к соответствующему параметру адаптера.
Если фильтр F
применяется к N
параметр th цели, тогда F
должен быть дескриптор метода, который берет точно один параметр. Тип F
's единственный параметр заменяет соответствующий тип параметра цели в получающемся адаптированном дескрипторе метода. Тип возврата F
должно быть идентичным соответствующему типу параметра цели.
Это - ошибка, если есть элементы filters
(нуль или не), которые не соответствуют позициям параметра в цели. Пример:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle upcase = lookup().findVirtual(String.class, "toUpperCase", methodType(String.class)); assertEquals("xy", (String) cat.invokeExact("x", "y")); MethodHandle f0 = filterArguments(cat, 0, upcase); assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy MethodHandle f1 = filterArguments(cat, 1, upcase); assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY MethodHandle f2 = filterArguments(cat, 0, upcase, upcase); assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
Вот псевдокод для получающегося адаптера:
V target(P... p, A[i]... a[i], B... b); A[i] filter[i](V[i]); T adapter(P... p, V[i]... v[i], B... b) { return target(p..., f[i](v[i])..., b...); }
target
- дескриптор метода, чтобы вызвать после параметров фильтруетсяpos
- позиция первого параметра фильтруfilters
- метод обрабатывает, чтобы вызвать первоначально на фильтруемых параметрахNullPointerException
- если цель является нулем или если filters
массив является нулемIllegalArgumentException
- если ненулевой элемент filters
не соответствует соответствующий тип параметра цели как описано выше, или если pos+filters.length
больше чем target.type().parameterCount()
public static MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter)
Если цель возвращает значение, фильтр должен признать что значение как его единственный параметр. Если цель возвращается пусто, фильтр не должен принять параметры.
Тип возврата фильтра заменяет тип возврата цели в получающемся адаптированном дескрипторе метода. Тип параметра фильтра (если кто-либо) должен быть идентичным типу возврата цели. Пример:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); MethodHandle length = lookup().findVirtual(String.class, "length", methodType(int.class)); System.out.println((String) cat.invokeExact("x", "y")); // xy MethodHandle f0 = filterReturnValue(cat, length); System.out.println((int) f0.invokeExact("x", "y")); // 2
Вот псевдокод для получающегося адаптера:
V target(A...); T filter(V); T adapter(A... a) { V v = target(a...); return filter(v); } // and if the target has a void return: void target2(A...); T filter2(); T adapter2(A... a) { target2(a...); return filter2(); } // and if the filter has a void return: V target3(A...); void filter3(V); void adapter3(A... a) { V v = target3(a...); filter3(v); }
target
- дескриптор метода, чтобы вызвать прежде, чем фильтровать возвращаемое значениеfilter
- дескриптор метода, чтобы обратиться к возвращаемому значениюNullPointerException
- если любым параметром является нульIllegalArgumentException
- если список параметров filter
не соответствует тип возврата цели как описано вышеpublic static MethodHandle foldArguments(MethodHandle target, MethodHandle combiner)
Предварительная обработка выполняется combiner
, второй дескриптор метода. Из параметров, которые передают к адаптеру, первому N
параметры копируются в объединитель, который тогда вызывают. (Здесь, N
определяется как количество параметра объединителя.) После этого управление передает к цели с любым следствием объединителя, вставленного перед оригиналом N
входящие параметры.
Если объединитель возвращает значение, первый тип параметра цели должен быть идентичным с типом возврата объединителя, и следующим N
типы параметра цели должны точно соответствовать параметры объединителя.
Если у объединителя будет пустой возврат, то никакой результат не будет вставлен, и первое N
типы параметра цели должны точно соответствовать параметры объединителя.
Получающийся адаптер является тем же самым типом как цель, за исключением того, что первый тип параметра отбрасывается, если это соответствует результату объединителя.
(Отметьте это dropArguments
может использоваться, чтобы удалить любые параметры, что или объединитель или цель не хотят получать. Если некоторые из входящих параметров предназначаются только для объединителя, рассматривают использование asCollector
вместо этого, так как те параметры не должны будут быть живыми на стеке на записи в цель.) Пример:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class, "println", methodType(void.class, String.class)) .bindTo(System.out); MethodHandle cat = lookup().findVirtual(String.class, "concat", methodType(String.class, String.class)); assertEquals("boojum", (String) cat.invokeExact("boo", "jum")); MethodHandle catTrace = foldArguments(cat, trace); // also prints "boo": assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
Вот псевдокод для получающегося адаптера:
// there are N arguments in A... T target(V, A[N]..., B...); V combiner(A...); T adapter(A... a, B... b) { V v = combiner(a...); return target(v, a..., b...); } // and if the combiner has a void return: T target2(A[N]..., B...); void combiner2(A...); T adapter2(A... a, B... b) { combiner2(a...); return target2(a..., b...); }
target
- дескриптор метода, чтобы вызвать после параметров объединяетсяcombiner
- дескриптор метода, чтобы вызвать первоначально на входящих параметрахNullPointerException
- если любым параметром является нульIllegalArgumentException
- если combiner
's тип возврата является непустым а не то же самое как первый тип параметра цели, или если начальная буква N
типы параметра цели (пропуск того, соответствующего combiner
's тип возврата), не идентичны с типами параметра combiner
public static MethodHandle guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)
Вот псевдокод для получающегося адаптера:
Отметьте что тестовые параметры (boolean test(A...); T target(A...,B...); T fallback(A...,B...); T adapter(A... a,B... b) { if (test(a...)) return target(a..., b...); else return fallback(a..., b...); }
a...
в псевдокоде), не может быть изменен выполнением теста, и так передаются неизменный от вызывающей стороны до цели или нейтрализации как соответствующий.test
- дескриптор метода, используемый для теста, должен возвратиться булевtarget
- дескриптор метода, чтобы вызвать, если тест передаетfallback
- дескриптор метода, чтобы вызвать, если тест перестал работатьNullPointerException
- если каким-либо параметром является нульIllegalArgumentException
- если test
не возвращается булев, или если все три типа метода не соответствуют (с типом возврата test
измененный на соответствие та из цели).public static MethodHandle catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler)
У цели и обработчика должны быть тот же самый соответствующий параметр и типы возврата, за исключением того, что обработчик может опустить запаздывать параметры (так же к предикату в guardWithTest
). Кроме того, у обработчика должен быть дополнительный ведущий параметр exType
или супертип.
Вот псевдокод для получающегося адаптера:
Отметьте что сохраненные параметры (T target(A..., B...); T handler(ExType, A...); T adapter(A... a, B... b) { try { return target(a..., b...); } catch (ExType ex) { return handler(ex, a...); } }
a...
в псевдокоде), не может быть изменен выполнением цели, и так передаются неизменный с вызывающей стороны на обработчик, если обработчик вызывается. Цель и обработчик должны возвратить тот же самый тип, даже если обработчик всегда бросает. (Это могло бы произойти, например, потому что обработчик моделирует a finally
пункт). Чтобы создать такой обработчик броска, составьте логику создания обработчика с throwException
, чтобы создать дескриптор метода корректного типа возврата.
target
- дескриптор метода, чтобы вызватьexType
- тип исключения, которое поймает обработчикhandler
- дескриптор метода, чтобы вызвать, если соответствующее исключение выдаетсяNullPointerException
- если каким-либо параметром является нульIllegalArgumentException
- если handler
не принимает данный тип исключения, или если типы дескриптора метода не соответствуют в их типах возврата и их соответствующих параметрахpublic static MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType)
exType
. Дескриптор метода примет единственный параметр exType
, и сразу бросьте это как исключение. Тип метода номинально определит возврат returnType
. Тип возврата может быть чем-либо удобным: Это не имеет значения для поведения дескриптора метода, так как это никогда не будет обычно возвращаться.NullPointerException
- если любым параметром является нуль
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE. Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2013, Oracle и/или его филиалы. Все права защищены.
Проект сборка-b92