MethodHandle.AsSpreader 方法

定义

重载

AsSpreader(Class, Int32)

<使 em>数组分布</em> 方法句柄接受尾随数组参数,并将其元素分散为位置参数。

AsSpreader(Int32, Class, Int32)

<使 em>数组分布</em> 方法句柄接受位于给定位置的数组参数,并将其元素分散为位置参数代替数组。

AsSpreader(Class, Int32)

<使 em>数组分布</em> 方法句柄接受尾随数组参数,并将其元素分散为位置参数。

[Android.Runtime.Register("asSpreader", "(Ljava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_Ljava_lang_Class_IHandler", ApiSince=26)]
public virtual Java.Lang.Invoke.MethodHandle? AsSpreader (Java.Lang.Class? arrayType, int arrayLength);
[<Android.Runtime.Register("asSpreader", "(Ljava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_Ljava_lang_Class_IHandler", ApiSince=26)>]
abstract member AsSpreader : Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle
override this.AsSpreader : Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle

参数

arrayType
Class

通常 Object[],从中提取分布自变量的数组参数的类型

arrayLength
Int32

要从传入数组参数分布的参数数

返回

在调用原始方法句柄之前,新方法句柄可分散其最终数组参数

属性

注解

<使 em>数组分布</em> 方法句柄接受尾随数组参数,并将其元素分散为位置参数。 新方法句柄根据其 目标调整当前方法句柄。 适配器的类型将与目标的类型相同,只是目标类型的最终 arrayLength 参数被类型的 arrayType单个数组参数替换。

如果数组元素类型与原始目标上任何相应的参数类型不同,则原始目标将改编为直接获取数组元素,就像通过调用一 #asType asType样。

调用时,适配器会将一个尾随数组参数替换为数组的元素,每个元素作为其自己的参数来替换目标。 (保留参数的顺序。它们通过强制转换和/或取消装箱到目标的尾随参数类型进行成对转换。 最后调用目标。 目标最终返回的内容由适配器保持不变。

在调用目标之前,适配器会验证数组是否包含足够多的元素,以便为目标方法句柄提供正确的参数计数。 (如果需要零个元素,则数组也可能为 null。

调用适配器时,所提供 array 参数的长度将像按 array.length 字节码或 arraylength 字节码一样进行查询。 如果适配器接受零长度尾随数组参数,则array提供的自变量可以是零长度数组,null或者;否则,如果数组是null,并且如果数组没有正确数量的元素,则适配器将引发IllegalArgumentExceptionNullPointerException数组。

下面是数组分布方法句柄的一些简单示例: <blockquote>

{@code
            MethodHandle equals = publicLookup()
              .findVirtual(String.class, "equals", methodType(boolean.class, Object.class));
            assert( (boolean) equals.invokeExact("me", (Object)"me"));
            assert(!(boolean) equals.invokeExact("me", (Object)"thee"));
            // spread both arguments from a 2-array:
            MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
            assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
            assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
            // try to spread from anything but a 2-array:
            for (int n = 0; n <= 10; n++) {
              Object[] badArityArgs = (n == 2 ? new Object[0] : new Object[n]);
              try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
              catch (IllegalArgumentException ex) { } // OK
            }
            // spread both arguments from a String array:
            MethodHandle eq2s = equals.asSpreader(String[].class, 2);
            assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
            assert(!(boolean) eq2s.invokeExact(new String[]{ "me", "thee" }));
            // spread second arguments from a 1-array:
            MethodHandle eq1 = equals.asSpreader(Object[].class, 1);
            assert( (boolean) eq1.invokeExact("me", new Object[]{ "me" }));
            assert(!(boolean) eq1.invokeExact("me", new Object[]{ "thee" }));
            // spread no arguments from a 0-array or null:
            MethodHandle eq0 = equals.asSpreader(Object[].class, 0);
            assert( (boolean) eq0.invokeExact("me", (Object)"me", new Object[0]));
            assert(!(boolean) eq0.invokeExact("me", (Object)"thee", (Object[])null));
            // asSpreader and asCollector are approximate inverses:
            for (int n = 0; n <= 2; n++) {
                for (Class<?> a : new Class<?>[]{Object[].class, String[].class, CharSequence[].class}) {
                    MethodHandle equals2 = equals.asSpreader(a, n).asCollector(a, n);
                    assert( (boolean) equals2.invokeWithArguments("me", "me"));
                    assert(!(boolean) equals2.invokeWithArguments("me", "thee"));
                }
            }
            MethodHandle caToString = publicLookup()
              .findStatic(Arrays.class, "toString", methodType(String.class, char[].class));
            assertEquals("[A, B, C]", (String) caToString.invokeExact("ABC".toCharArray()));
            MethodHandle caString3 = caToString.asCollector(char[].class, 3);
            assertEquals("[A, B, C]", (String) caString3.invokeExact('A', 'B', 'C'));
            MethodHandle caToString2 = caString3.asSpreader(char[].class, 2);
            assertEquals("[A, B, C]", (String) caToString2.invokeExact('A', "BC".toCharArray()));
            }

</blockquote>

适用于 . 的 java.lang.invoke.MethodHandle.asSpreader(java.lang.Class<?>, int)Java 文档

本页的某些部分是根据 Android 开放源代码项目创建和共享的工作进行的修改,并根据 Creative Commons 2.5 属性许可证中所述的术语使用。

适用于

AsSpreader(Int32, Class, Int32)

<使 em>数组分布</em> 方法句柄接受位于给定位置的数组参数,并将其元素分散为位置参数代替数组。

[Android.Runtime.Register("asSpreader", "(ILjava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_ILjava_lang_Class_IHandler", ApiSince=33)]
public virtual Java.Lang.Invoke.MethodHandle? AsSpreader (int spreadArgPos, Java.Lang.Class? arrayType, int arrayLength);
[<Android.Runtime.Register("asSpreader", "(ILjava/lang/Class;I)Ljava/lang/invoke/MethodHandle;", "GetAsSpreader_ILjava_lang_Class_IHandler", ApiSince=33)>]
abstract member AsSpreader : int * Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle
override this.AsSpreader : int * Java.Lang.Class * int -> Java.Lang.Invoke.MethodHandle

参数

spreadArgPos
Int32

参数列表中应开始分布的位置(从零开始的索引)。

arrayType
Class

通常 Object[],从中提取分布自变量的数组参数的类型

arrayLength
Int32

要从传入数组参数分布的参数数

返回

在调用原始方法句柄之前,新方法句柄将数组参数分散在给定位置

属性

注解

<使 em>数组分布</em> 方法句柄接受位于给定位置的数组参数,并将其元素分散为位置参数代替数组。 新方法句柄根据其 目标调整当前方法句柄。 适配器的类型将与目标的类型相同,但 arrayLength 目标类型的参数(从从零开始的位置 spreadArgPos开始)被类型的 arrayType单个数组参数替换。

此方法的行为非常类似 #asSpreader(Class, int),但接受一个附加 spreadArgPos 参数来指示应在参数列表中发生分布的位置。

已在 9 中添加。

适用于 . 的 java.lang.invoke.MethodHandle.asSpreader(int, java.lang.Class<?>, int)Java 文档

本页的某些部分是根据 Android 开放源代码项目创建和共享的工作进行的修改,并根据 Creative Commons 2.5 属性许可证中所述的术语使用。

适用于