語言

MethodHandle.AsVarargsCollector(Class) 方法

定義

它製作了一個 <em>變數 arity</em> 適配器,能夠接受任意數量的後方位置參數並將其收集成陣列參數。

[Android.Runtime.Register("asVarargsCollector", "(Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", "GetAsVarargsCollector_Ljava_lang_Class_Handler", ApiSince=26)]
public virtual Java.Lang.Invoke.MethodHandle? AsVarargsCollector(Java.Lang.Class? arrayType);
[<Android.Runtime.Register("asVarargsCollector", "(Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;", "GetAsVarargsCollector_Ljava_lang_Class_Handler", ApiSince=26)>]
abstract member AsVarargsCollector : Java.Lang.Class -> Java.Lang.Invoke.MethodHandle
override this.AsVarargsCollector : Java.Lang.Class -> Java.Lang.Invoke.MethodHandle

參數

arrayType
Class

通常 Object[]是陣列參數的類型,該參數將收集參數

傳回

一個新的方法句柄,可以在呼叫原始方法句柄前,收集任意數量的尾隨參數到陣列中

屬性

備註

它製作了一個 <em>變數 arity</em> 適配器,能夠接受任意數量的後方位置參數並將其收集成陣列參數。

介面卡的類型與行為與目標的類型與行為相同,但某些 invoke 和 asType 請求可能導致後方位置參數被收集到目標的後方參數中。 此外,即使目標的最後參數類型不同,MethodType#lastParameterType 的最後參數類型也會是 arrayType。

若方法的 handle 已經是可變元數且其後置參數型別與 相同,則此轉換可能會返回thisarrayType。

當以 呼叫時 #invokeExact invokeExact,介面卡會呼叫目標且不更改參數。 (<em>註:</em> 此行為與 #asCollector 固定元數收集器不同,因為它接受整個不定長度陣列,而非固定數量的參數。)

當 以 plain, inprecise #invoke invoke呼叫 時,若呼叫者類型與適配器相同,轉接器會呼叫目標,且 。invokeExact (這是類型匹配時 invoke 的正常行為。)

否則,若呼叫者與介面卡元數相同,且呼叫者的後置參數型別與介面卡的後置參數型別相同或可指派,則參數與回傳值會成對轉換,就像在固定元數方法的 handle 上 #asType asType 一樣。

否則,元數不同,或是轉接器的後置參數型別無法從對應呼叫型別指派。 此時,適配器會將從原始後置參數位置開始的所有尾隨參數替換為一個新的陣列,該陣列 arrayType的元素依序組成被替換的參數。

呼叫者型別必須提供至少足夠且正確的參數,以滿足目標在後方陣列參數前的位置參數的要求。 因此,呼叫者至少必須提供 N-1 參數,其中 N 是目標的元數。 此外,必須存在從輸入參數轉換到目標參數的轉換。 如同其他素 invoke的用法,若未滿足這些基本條件,則可擲出 a WrongMethodTypeException 。

在所有情況下,目標最終回傳的訊號都會被轉接器不改。

在最後一種情況下,就像目標方法的 handle 暫時用 #asCollector 固定 arity collector 調整到呼叫者所需的 arity 一樣。 (如同 asCollector,若陣列長度為零,則可使用共享常數代替新陣列。如果隱含的呼叫asCollector會拋出或IllegalArgumentExceptionWrongMethodTypeException,則呼叫變元適配器必須拋出WrongMethodTypeException。)

的 #asType asType 行為也專門用於可變元數適配器,以維持不變性,即純且不精確 invoke 的狀態總是等同於調 asType 校目標類型,接著是 invokeExact。 因此,當且僅當可變元數介面卡與請求的類型在元數或後引參數類型上不同時,可變元數介面卡會 asType 透過建構固定元值收集器來回應請求。 結果的固定元數收集器會透過成對轉換(如有需要)進一步調整其類型,就像透過另一種應用 。asType

當方法柄是透過執行 ldc 常數指令 CONSTANT_MethodHandle 而得到,且目標方法標記為可變元數方法(修飾位 0x0080元為 ),該方法句柄會接受多個元數,就像方法柄常數是透過呼叫 所 asVarargsCollector建立的。

為了建立一個收集參數數量且型別反映此數的收集適配器,請 #asCollector asCollector 用

除非有文件說明,否則沒有任何方法句柄轉換會產生具有可變元數的新方法句柄。 因此,除了 asVarargsCollector 和 withVarargs之外,所有在 和 MethodHandles 中MethodHandle的方法都會回傳固定元數的方法 handle,除非指定回傳其原始運算元(例如asType方法 handle 自身型別的操作數)。

呼叫 asVarargsCollector 已為可變元數的方法代言會產生一個類型與行為相同的方法代言會。 它可能會(也可能不會)回傳原始的變元率方法的 handle。

以下是一個列表製作變數元數方法的範例: <blockquote>

{@code
            MethodHandle deepToString = publicLookup()
              .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
            MethodHandle ts1 = deepToString.asVarargsCollector(Object[].class);
            assertEquals("[won]",   (String) ts1.invokeExact(    new Object[]{"won"}));
            assertEquals("[won]",   (String) ts1.invoke(         new Object[]{"won"}));
            assertEquals("[won]",   (String) ts1.invoke(                      "won" ));
            assertEquals("[[won]]", (String) ts1.invoke((Object) new Object[]{"won"}));
            // findStatic of Arrays.asList(...) produces a variable arity method handle:
            MethodHandle asList = publicLookup()
              .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class));
            assertEquals(methodType(List.class, Object[].class), asList.type());
            assert(asList.isVarargsCollector());
            assertEquals("[]", asList.invoke().toString());
            assertEquals("[1]", asList.invoke(1).toString());
            assertEquals("[two, too]", asList.invoke("two", "too").toString());
            String[] argv = { "three", "thee", "tee" };
            assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
            assertEquals("[three, thee, tee]", asList.invoke((Object[])argv).toString());
            List ls = (List) asList.invoke((Object)argv);
            assertEquals(1, ls.size());
            assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
            }

</區塊引用>

<em>討論:</em> 這些規則設計為 Java 可變元數方法規則的動態型別變體。 在這兩種情況下,呼叫變元數方法或方法句柄的使用者可以傳遞零個或多個位置參數,或傳遞任意長度的預先收集陣列。 使用者應了解最後一個參數的特殊角色,以及型別匹配對該最終參數的影響,決定單一尾隨參數是被解讀為整個陣列還是單一元素。 請注意,尾隨參數的動態型別不影響此決策,僅比較呼叫站點的符號型別描述符與方法句柄型別描述符。)

的 java.lang.invoke.MethodHandle.asVarargsCollector(java.lang.Class<?>)Java 檔。

本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。

適用於