public class MethodHandles extends Object
Modifier and Type | Class and Description |
---|---|
static class |
MethodHandles.Lookup
查找对象是一个用于创建方法句柄的工厂,当创建需要访问检查时。
|
Modifier and Type | Method and Description |
---|---|
static MethodHandle |
arrayElementGetter(类<?> arrayClass)
产生一个方法来处理对数组元素的读取访问。
|
static MethodHandle |
arrayElementSetter(类<?> arrayClass)
产生一个方法处理给数组元素的写访问权限。
|
static MethodHandle |
catchException(MethodHandle target, 类<? extends Throwable> exType, MethodHandle handler)
通过在异常处理程序中运行它,使一个适应目标方法句柄的方法处理。
|
static MethodHandle |
collectArguments(MethodHandle target, int pos, MethodHandle filter)
通过预处理与一个过滤器(另一个方法句柄)的参数的子序列来调整目标方法句柄。
|
static MethodHandle |
constant(类<?> type, Object value)
产生一个请求的返回类型的方法句柄,它每次调用时返回给定的常数值。
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, 类<?>... valueTypes)
产生的方法处理,会丢弃一些虚拟的参数调用其他一些指定的空目标方法处理前。
|
static MethodHandle |
dropArguments(MethodHandle target, int pos, List<类<?>> valueTypes)
产生的方法处理,会丢弃一些虚拟的参数调用其他一些指定的空目标方法处理前。
|
static MethodHandle |
exactInvoker(MethodType type)
产生了一种特殊的调用方法处理可用于调用任何方法处理给定类型的,如
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(类<?> type)
产生调用时返回其唯一参数的方法句柄。
|
static MethodHandle |
insertArguments(MethodHandle target, int pos, Object... values)
提供一个目标方法处理在方法句柄调用之前的一个或多个绑定参数。
|
static MethodHandle |
invoker(MethodType type)
产生了一种特殊的调用方法处理可用于调用任何方法处理符合给定的类型,如
invoke 。
|
static MethodHandles.Lookup |
lookup()
返回一个
lookup object 全功能模拟都支持对方的字节码的行为。
|
static MethodHandle |
permuteArguments(MethodHandle target, MethodType newType, int... reorder)
生产法处理适应给定的方法的调用顺序处理一个新的类型,通过重新排列参数。
|
static MethodHandles.Lookup |
publicLookup()
返回一个
lookup object 是值得信赖的微创。
|
static <T extends Member> |
reflectAs(类<T> expected, MethodHandle target)
执行检查的“裂缝”的
direct method handle。
|
static MethodHandle |
spreadInvoker(MethodType type, int leadingArgCount)
产生的方法处理这将调用任何方法处理给定的
type ,与给定数量的尾参数由一个单一的尾
Object[] 阵列取代。
|
static MethodHandle |
throwException(类<?> returnType, 类<? extends Throwable> exType)
产生的方法处理,将给定的
exType 例外。
|
public static MethodHandles.Lookup lookup()
lookup object
全功能模拟都支持对方的字节码的行为。这些功能包括
private access给调用者。在查找对象的工厂方法可以创建
direct method handles任何成员,调用者通过字节码访问,包括保护和私人领域和方法。此查找对象是一个可能被委托给受信任代理的能力。不保存它的地方,不受信任的代码可以访问它。
此方法是调用方敏感的,这意味着它可能会返回不同的值给不同的调用方。
对于任何给定的调用类C
,查询返回的对象需要任何查找对象由JVM提供给在同一调用类C
执行invokedynamic instruction Bootstrap方法等效的能力。
public static MethodHandles.Lookup publicLookup()
lookup object
是值得信赖的微创。它只能用于创建用于可公开访问的字段和方法的方法句柄。
作为一个纯粹的公约,这将Object
lookup class查找对象。
讨论:查找类可以更改为任何其他类C
使用publicLookup().in(C.class)
表达形式。由于所有类都有相同的对公共名称的访问,这样的变化将赋予没有新的访问权限。公共查询对象总是受security manager checks。另外,它无法访问caller sensitive methods。
public static <T extends Member> T reflectAs(类<T> expected, MethodHandle target)
Lookup.revealDirect
获得符号引用,然后叫
MethodHandleInfo.reflectAs
解决成员的象征意义。
如果存在安全管理器,它的checkPermission
方法称为一个ReflectPermission("suppressAccessChecks")
许可。
T
-结果所期望的类型,要么
Member
或亚型
target
-一个直接的方法处理裂缝为符号参考组件
expected
-代表期望的结果类型
T
类对象
SecurityException
如果打电话的人是不是叫
setAccessible
特权
NullPointerException
如果任一参数是
null
IllegalArgumentException
-如果目标不是一个直接的方法处理
ClassCastException
-如果成员不是预期的类型
public static MethodHandle arrayElementGetter(类<?> arrayClass) throws IllegalArgumentException
int
。
arrayClass
-数组类型
NullPointerException
-如果参数为空
IllegalArgumentException
-如果arrayclass不是数组类型
public static MethodHandle arrayElementSetter(类<?> arrayClass) throws IllegalArgumentException
arrayClass
-数组的类
NullPointerException
-如果参数为空
IllegalArgumentException
-如果arrayclass不是数组类型
public static MethodHandle spreadInvoker(MethodType type, int leadingArgCount)
type
,与给定数量的尾参数由一个单一的尾
Object[]
阵列取代。由此产生的调用将使用下面的参数处理方法:这种方法
MethodHandle
目标leadingArgCount
)Object[]
阵列参数调用程序会调用它的目标像一声invoke
与表示type
。就是说,如果目标是给定的type
,它会像invokeExact
;否则它就好像asType
是用来转换目标所需的type
。
返回调用程序的类型将不给予type
,而是将除第一leadingArgCount
由一个单一的阵列式Object[]
取代所有参数,这将是最后一个参数。
调用其目标之前,调用程序将最终的阵列,将参考模型是必要的,而且还要将拓宽原始参数。如果,当调用被调用,提供的数组参数没有正确数量的元素,调用会抛出一个IllegalArgumentException
代替调用目标。
此方法相当于下面的代码(虽然它可能更有效):
投不反射或安全例外。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()
包容,或者产生的方法处理的类型会
too many parameters
public static MethodHandle exactInvoker(MethodType type)
invokeExact
。由此产生的调用将有一个类型,正好等于所需类型,除了它将接受型
MethodHandle
额外的主要论点。
此方法等效于下面的代码(尽管它可能是更有效的):publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
讨论:调用方法处理可以是有用的工作时变未知类型的处理方法。例如,模拟invokeExact
调用变量的方法处理M
,提取其型T
,查找T
调用方法X
,并调用调用的方法,为X.invoke(T, A...)
。(这并不是说X.invokeExact
,因为类型T
是未知的。)如果蔓延,收集,或其他参数的转换是必需的,他们可以应用一次调用X
和重复使用在许多M
方法处理的值,只要是与X
类型兼容。
(注:调用方法是不通过反射API的核心。试图呼吁宣布invokeexact java.lang.reflect.method.invoke或调用方法将提高UnsupportedOperationException。)
此方法不抛出任何反射或安全异常。
type
-目标型
IllegalArgumentException
如果产生的方法处理的类型会
too many parameters
public static MethodHandle invoker(MethodType type)
invoke
。由此产生的调用将有一个类型,正好等于所需类型,除了它将接受型
MethodHandle
额外的主要论点。
调用其目标之前,如果目标不同于预期的类型,调用程序将参考下必要和箱、拆箱、或扩大原始值,如asType
。同样,返回值将被转换为必要的。如果目标是一个variable arity method handle,所需数量的转换将,又如asType
。
此方法等效于下面的代码(尽管它可能是更有效的):publicLookup().findVirtual(MethodHandle.class, "invoke", type)
讨论:一个general method type是其中只提到Object
参数和返回值。这种类型的调用可以调用任何方法处理相同数量的一般类型。
(注:调用方法是不通过反射API的核心。试图呼吁宣布invokeexact java.lang.reflect.method.invoke或调用方法将提高UnsupportedOperationException。)
此方法不抛出任何反射或安全异常。
type
-目标型
IllegalArgumentException
如果产生的方法处理的类型会
too many parameters
public static MethodHandle explicitCastArguments(MethodHandle target, MethodType newType)
如果原始类型和新类型是相等的,则返回目标。
同样的转换都可以作为MethodHandle.asType
,和一些附加的转换也是如果转换失败的应用。给定类型的T0,T1,下列转换应用如果可能的话,在任何转换或代替了asType
:
(x & 1) != 0
。target
-处理方法调用后的参数重新输入
newType
--新方法处理预期的类型
NullPointerException
-如果任一参数为null
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(类<?> type, Object value)
在返回方法句柄之前,将传递的值转换为所请求的类型。如果所请求的类型是原始的,则尝试扩大原始转换,尝试其他引用转换。
返回的方法处理相当于identity(type).bindTo(value)
。
type
-所需的处理方法的返回类型
value
的价值回归
NullPointerException
-如果
type
参数为null
ClassCastException
-如果该值不能转换为所需的返回类型
IllegalArgumentException
如果给定类型
void.class
public static MethodHandle identity(类<?> type)
type
-唯一的参数和所需的方法处理返回值的类型
NullPointerException
-如果参数为空
IllegalArgumentException
如果给定类型
void.class
public static MethodHandle insertArguments(MethodHandle target, int pos, Object... values)
新方法句柄的类型将从原来的目标类型下拉绑定参数的类型,因为新的方法句柄将不再需要由它的调用方提供的参数。
每个给定的参数对象必须匹配相应的绑定参数类型。如果绑定的参数类型是一个原始的,争论的对象必须是一个包装,并将取消装箱产生的原始值。
pos
参数选取的参数是被束缚的。它可以零和nulln-1之间的范围内(含),在nulln是目标方法处理和零个数的值是数组的长度。
target
-处理方法调用插入后的争论
pos
-如何插入参数(零为第一)
values
-参数序列插入
NullPointerException
-如果目标或
values
数组是空的
MethodHandle.bindTo(java.lang.Object)
public static MethodHandle dropArguments(MethodHandle target, int pos, List<类<?>> valueTypes)
的pos
说法可能零和nulln之间的范围内,在nulln是目标的数量。如果pos
为零,虚拟的争论将先于目标的真正的辩论;如果pos
是nulln他们会来后。
例子:
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
型(S)的参数(S)下降
pos
-第一个参数的位置下降(零的左边)
NullPointerException
-如果目标是零,或者如果
valueTypes
列表或其任何元素是空的
IllegalArgumentException
-如果
valueTypes
任何元素
void.class
,或者如果
pos
阴性或超过目标的数量,或如果新方法处理的类型会有太多的参数
public static MethodHandle dropArguments(MethodHandle target, int pos, 类<?>... valueTypes)
的pos
说法可能零和nulln之间的范围内,在nulln是目标的数量。如果pos
为零,虚拟的争论将先于目标的真正的辩论;如果pos
是nulln他们会来后。
例子:
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
型(S)的参数(S)下降
pos
-第一个参数的位置下降(零的左边)
NullPointerException
-如果目标是零,或者如果
valueTypes
阵列或其任何元素是空的
IllegalArgumentException
-如果
valueTypes
任何元素
void.class
,或者如果
pos
阴性或超过目标的数量,或如果新方法处理的类型会
too many parameters
public static MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters)
预处理是由一个或多个方法进行处理,在filters
数组元素指定。过滤器的数组的第一个元素对应于目标的pos
论点等顺序。
数组中的空参数被视为身份函数,并将相应的参数保持不变。(如果数组中没有非空元素,则返回原始目标。)每个筛选器应用于适配器的相应参数。
如果过滤器F
适用于目标的N
th论点,然后F
必须以一个确切的参数处理方法。对F
的唯一参数的类型替换目标对应的实参类型的改编方法处理。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()
,或者产生的方法处理的类型会
too many parameters
public static MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter)
如果过滤器返回一个值,目标必须接受价值为pos
其论点的位置,之前和/或之后没有通过的滤波器参数。如果筛选器返回无效,目标必须接受没有传递到筛选器的所有参数。没有理由重新排序,并从过滤器返回结果代替(为了)最初通过适配器参数全序列。
参数类型(如果有)的过滤器更换零或一个参数目标的类型、位置pos
,在产生的适应方法处理。过滤器的返回类型(如果有)必须在位置pos
目标参数类型相同,并且目标参数是通过过滤器的返回值提供。
在所有的情况下,pos
必须大于或等于零,和pos
也必须小于或等于目标的数量。
例子:
import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... MethodHandle deepToString = publicLookup() .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class)); MethodHandle ts1 = deepToString.asCollector(String[].class, 1); assertEquals("[strange]", (String) ts1.invokeExact("strange")); MethodHandle ts2 = deepToString.asCollector(String[].class, 2); assertEquals("[up, down]", (String) ts2.invokeExact("up", "down")); MethodHandle ts3 = deepToString.asCollector(String[].class, 3); MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2); assertEquals("[top, [up, down], strange]", (String) ts3_ts2.invokeExact("top", "up", "down", "strange")); MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1); assertEquals("[top, [up, down], [strange]]", (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange")); MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3); assertEquals("[top, [[up, down, strange], charm], bottom]", (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
这是导致适配器的伪代码:
T target(A...,V,C...); V filter(B...); T adapter(A... a,B... b,C... c) { V v = filter(b...); return target(a...,v,c...); } // and if the filter has no arguments: T target2(A...,V,C...); V filter2(); T adapter2(A... a,C... c) { V v = filter2(); return target2(a...,v,c...); } // and if the filter has a void return: T target3(A...,C...); void filter3(B...); void adapter3(A... a,B... b,C... c) { filter3(b...); return target3(a...,c...); }
一个收集适配器collectArguments(mh, 0, coll)
相当于一首“褶皱”受影响的参数,然后下降,在单独的步骤如下:
如果目标处理方法没有参数除了消耗比结果(如果有)的滤波器mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2 mh = MethodHandles.foldArguments(mh, coll); //step 1
coll
,然后
collectArguments(mh, 0, coll)
相当于
filterReturnValue(coll, mh)
。如果过滤法处理
coll
消耗一个论点,并产生一个非空的结果,然后
collectArguments(mh, N, coll)
相当于
filterArguments(mh, N, coll)
。其它的对等是可能的但需要论证的排列。
target
-处理方法调用的参数序列后过滤
pos
-第一个适配器参数的位置通过过滤器,和/或目标参数接收滤波器的结果
filter
方法处理调用参数的顺序
NullPointerException
-如果任一参数为null
IllegalArgumentException
-如果
filter
返回类型是void,不作为目标的
pos
参数相同,或者如果
pos
不是0、目标性、包容性之间,或者产生的方法处理的类型会
too many parameters
foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)
,
filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...)
,
filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)
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
-如果任一参数为null
IllegalArgumentException
-如果
filter
参数列表不目标的返回类型为上述比赛
public static MethodHandle foldArguments(MethodHandle target, MethodHandle combiner)
预处理是通过combiner
,第二种方法处理。传递到适配器的参数,第一个参数是N
复制到组合,称为。(在这里,N
定义为组合,参数个数)之后,控制权传递到目标,从之前插入原N
传入的参数组合的结果。
如果合并器返回一个值,该目标的第一个参数的类型必须与合成器的返回类型是相同的,和下一步的目标N
参数类型必须完全匹配的组合参数。
如果合并有void返回,没有结果将被插入,和目标的第一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
-如果任一参数为null
IllegalArgumentException
-如果
combiner
的返回类型是非空,不一样的目标的第一个参数的类型,或者如果目标初始
N
参数类型(跳过一个匹配的
combiner
的返回类型)不与
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, 类<? 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...
在伪代码)不能由目标执行修改,所以从调用者的句柄,如果调用处理程序。
目标和处理程序必须返回同一类型,即使处理程序总是抛出。(这可能发生,例如,因为处理程序是模拟finally
条款)。创造这样一个抛处理,与throwException
构成处理器生成逻辑,为了创造一个正确的返回类型的方法处理。
target
方法处理呼叫
exType
-类型的异常处理程序将捕获的
handler
法处理如果匹配的异常被抛出的电话
NullPointerException
-如果任一参数为空
IllegalArgumentException
-如果
handler
不接受特定的异常类型,或如果方法处理类型不在其返回类型及相应的参数匹配
public static MethodHandle throwException(类<?> returnType, 类<? extends Throwable> exType)
exType
例外。处理方法将接受一个参数
exType
,立即把它作为例外。该方法将名义上指定返回的
returnType
。返回类型可能是任何方便的:它不重要的方法处理的行为,因为它将永远不会返回。
returnType
-所需的处理方法的返回类型
exType
-所需的处理方法的参数类型
NullPointerException
-如果任一参数为null
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.