MethodHandle Klasse

Definition

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

[Android.Runtime.Register("java/lang/invoke/MethodHandle", ApiSince=26, DoNotGenerateAcw=true)]
public abstract class MethodHandle : Java.Lang.Object
[<Android.Runtime.Register("java/lang/invoke/MethodHandle", ApiSince=26, DoNotGenerateAcw=true)>]
type MethodHandle = class
    inherit Object
Vererbung
MethodHandle
Attribute

Hinweise

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten. Diese Transformationen sind recht allgemein und umfassen Muster wie #asType Konvertierung, #bindTo Einfügen, java.lang.invoke.MethodHandles#dropArguments delete und java.lang.invoke.MethodHandles#filterArguments-Ersetzung.

<h1>Methodenhandle contents</h1> Methodenhandles werden dynamisch und stark gemäß ihren Parameter- und Rückgabetypen typisiert. Sie unterscheiden sich nicht durch den Namen oder die definierende Klasse ihrer zugrunde liegenden Methoden. Ein Methodenhandle muss mit einem symbolischen Typdeskriptor aufgerufen werden, der dem eigenen #type Typdeskriptor des Methodenhandles entspricht.

Jedes Methodenhandle meldet seinen Typdeskriptor über den #type type Accessor. Dieser Typdeskriptor ist ein java.lang.invoke.MethodType MethodType Objekt, dessen Struktur aus einer Reihe von Klassen besteht, von denen eine der Rückgabetyp der -Methode ist (oder void.class wenn keine).

Der Typ eines Methodenhandles steuert die Arten von Aufrufen, die es akzeptiert, und die Arten von Transformationen, die darauf angewendet werden.

Ein Methodenhandle enthält ein Paar von speziellen Aufrufmethoden namens #invokeExact invokeExact und #invoke invoke. Beide Aufrufmethoden bieten direkten Zugriff auf die dem Methodenhandle zugrunde liegende Methode, den Konstruktor, das Feld oder einen anderen Vorgang, der durch Transformationen von Argumenten und Rückgabewerten geändert wird. Beide Aufrufer akzeptieren Aufrufe, die genau dem eigenen Typ des Methodenhandles entsprechen. Der einfache, ungenaue Aufrufer akzeptiert auch einen Bereich anderer Aufruftypen.

Methodenhandles sind unveränderlich und weisen keinen sichtbaren Zustand auf. Natürlich können sie an zugrunde liegende Methoden oder Daten gebunden werden, die einen Zustand aufweisen. In Bezug auf das Java-Speichermodell verhält sich jedes Methodenhandle so, als ob alle seine (internen) Felder endgültige Variablen sind. Dies bedeutet, dass jedes für die Anwendung sichtbar gemachte Methodenhandle immer vollständig formatiert wird. Dies gilt auch dann, wenn das Methodenhandle über eine freigegebene Variable in einem Datenrennen veröffentlicht wird.

Methodenhandles können vom Benutzer nicht unterklassiert werden. Implementierungen können interne Unterklassen erstellen (oder auch nicht), von MethodHandle denen über den java.lang.Object#getClass Object.getClass Vorgang sichtbar sein kann. Der Programmierer sollte keine Schlussfolgerungen zu einem Methodenhandle aus seiner spezifischen Klasse ziehen, da sich die Klassenhierarchie der Methode (falls vorhanden) von Zeit zu Zeit oder zwischen Implementierungen verschiedener Anbieter ändern kann.

<h1>Methodenhandlekompilierung</h1> Ein Java-Methodenaufrufausdruck invokeExact namens oder invoke kann ein Methodenhandle aus dem Java-Quellcode aufrufen. Aus Sicht des Quellcodes können diese Methoden beliebige Argumente annehmen, und ihr Ergebnis kann in einen beliebigen Rückgabetyp umgewandelt werden. Formal wird dies erreicht, indem den Aufrufmethoden Object Rückgabetypen und Variablenaritätsargumente Object zugewiesen werden, aber sie haben eine zusätzliche Qualität namens <em>signature polymorphism</em> , die diese Aufruffreiheit direkt mit dem JVM-Ausführungsstapel verbindet.

Wie bei virtuellen Methoden üblich, rufen Sie eine Anweisung auf Quellebene auf invokeExact und invoke kompilieren sie in eine invokevirtual Anweisung. Ungewöhnlicher ist, dass der Compiler die tatsächlichen Argumenttypen aufzeichnen muss und möglicherweise keine Methodenaufrufkonvertierungen für die Argumente durchführt. Stattdessen muss es sie gemäß ihren eigenen nicht konvertierten Typen auf den Stapel pushen. Das Objekt des Methodenhandles selbst wird vor den Argumenten auf den Stapel gepusht. Der Compiler ruft dann das Methodenhandle mit einem symbolischen Typdeskriptor auf, der die Argument- und Rückgabetypen beschreibt.

Um einen vollständigen symbolischen Typdeskriptor auszugeben, muss der Compiler auch den Rückgabetyp bestimmen. Dies basiert auf einer Umwandlung des Methodenaufrufausdrucks, sofern vorhanden, oder andernfalls Object , wenn der Aufruf ein Ausdruck ist oder wenn void der Aufruf eine -Anweisung ist. Die Umwandlung kann in einen primitiven Typ (aber nicht void) erfolgen.

Als Eckfall erhält ein uncasted-Argument null den symbolischen Typdeskriptor von java.lang.Void. Die Mehrdeutigkeit mit dem Typ Void ist harmlos, da es außer dem NULL-Verweis keine Verweise vom Typ Void gibt.

<h1-Methodenhandleaufruf<>/h1> Wenn eine invokevirtual Anweisung zum ersten Mal ausgeführt wird, wird sie verknüpft, indem die Namen in der Anweisung symbolisch aufgelöst und überprüft werden, ob der Methodenaufruf statisch zulässig ist. Dies gilt für Aufrufe von invokeExact und invoke. In diesem Fall wird der vom Compiler ausgegebene symbolische Typdeskriptor auf die richtige Syntax überprüft, und die darin enthaltenen Namen werden aufgelöst. Daher wird eine invokevirtual Anweisung, die ein Methodenhandle aufruft, immer verknüpft, solange der symbolische Typdeskriptor syntaktisch wohlgeformt ist und die Typen vorhanden sind.

Wenn nach der invokevirtual Verknüpfung ausgeführt wird, wird der Typ des empfangenden Methodenhandles zuerst von der JVM überprüft, um sicherzustellen, dass er mit dem symbolischen Typdeskriptor übereinstimmt. Wenn die Typübereinstimmung fehlschlägt, bedeutet dies, dass die Methode, die der Aufrufer aufruft, im einzelnen aufgerufenen Methodenhandle nicht vorhanden ist.

Im Fall von invokeExactmuss der Typdeskriptor des Aufrufs (nach dem Auflösen symbolischer Typnamen) genau mit dem Methodentyp des empfangenden Methodenhandles übereinstimmen. Bei einfachen, ungenauen invokemuss der aufgelöste Typdeskriptor ein gültiges Argument für die -Methode des Empfängers #asType asType sein. Daher ist "plain invoke " mehr freizügiger als invokeExact.

Nach dem Typabgleich wird die invokeExact dem Methodenhandle zugrunde liegende Methode (oder ggf. ein anderes Verhalten) direkt und sofort aufgerufen.

Ein Aufruf von plain invoke funktioniert genauso wie ein Aufruf von invokeExact, wenn der vom Aufrufer angegebene symbolische Typdeskriptor genau mit dem eigenen Typ des Methodenhandles übereinstimmt. Wenn ein Typkonflikt vorliegt, versucht, invoke den Typ des empfangenden Methodenhandles anzupassen, als ob durch einen Aufruf #asType asTypevon , um ein genau bestimmbares Methodenhandle M2abzurufen. Dies ermöglicht eine leistungsfähigere Aushandlung des Methodentyps zwischen Aufrufer und Aufgerufenem.

(<em>Hinweis:</em> Der angepasste Methodenhandle M2 ist nicht direkt beobachtbar, und implementierungen müssen ihn daher nicht materialisieren.)

<h1>Aufrufüberprüfung</h1> In typischen Programmen ist der Abgleich des Methodenhandles in der Regel erfolgreich. Wenn jedoch eine Übereinstimmung fehlschlägt, löst WrongMethodTypeExceptiondie JVM entweder direkt (im Fall von invokeExact) oder indirekt als ob durch einen fehlgeschlagenen Aufruf asType von (im Fall von invoke) aus.

Daher kann ein Methodentypkonflikt, der als Verknüpfungsfehler in einem statisch typisierten Programm angezeigt werden kann, als dynamisch WrongMethodTypeException in einem Programm angezeigt werden, das Methodenhandles verwendet.

Da Methodentypen "live" Class -Objekte enthalten, berücksichtigt der Methodentypabgleich sowohl Typennamen als auch Klassenladeprogramme. Selbst wenn ein Methodenhandle M in einem Klassenladeprogramm L1 erstellt und in einem anderen L2verwendet wird, sind Methodenhandleaufrufe typsicher, da der symbolische Typdeskriptor des Aufrufers, wie in L2aufgelöst, mit dem symbolischen Typdeskriptor der ursprünglich aufgerufenen Methode abgeglichen wird, wie in L1aufgelöst. Die Auflösung in L1 erfolgt, wenn M erstellt und ihr Typ zugewiesen wird, während die Auflösung in L2 erfolgt, wenn die invokevirtual Anweisung verknüpft ist.

Abgesehen von der Überprüfung von Typdeskriptoren ist die Fähigkeit eines Methodenhandles, die zugrunde liegende Methode aufzurufen, uneingeschränkt. Wenn ein Methodenhandle für eine nicht öffentliche Methode von einer Klasse gebildet wird, die Zugriff auf diese Methode hat, kann das resultierende Handle an beliebiger Stelle von jedem Aufrufer verwendet werden, der einen Verweis darauf erhält.

Anders als bei der Core Reflection-API, bei der der Zugriff jedes Mal überprüft wird, wenn eine reflektierende Methode aufgerufen wird, wird die Zugriffsüberprüfung des Methodenhandles ausgeführt, wenn das Methodenhandle erstellt wird. Im Fall von ldc (siehe unten) wird die Zugriffsüberprüfung im Rahmen der Verknüpfung des Konstantenpooleintrags durchgeführt, der dem Handle der konstanten Methode zugrunde liegt.

Daher sollten Umgange mit nicht öffentlichen Methoden oder methoden in nicht öffentlichen Klassen im Allgemeinen geheim gehalten werden. Sie sollten nicht an nicht vertrauenswürdigen Code übergeben werden, es sei denn, ihre Verwendung aus dem nicht vertrauenswürdigen Code wäre harmlos.

<h1>Methodenhandleserstellung</h1> Java-Code kann ein Methodenhandle erstellen, das direkt auf alle Methoden, Konstruktoren oder Felder zugreift, auf die dieser Code zugreifen kann. Dies erfolgt über eine reflektierende, funktionsbasierte API namens java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup Beispielsweise kann aus ein statisches Methodenhandle abgerufen java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStaticwerden. Es gibt auch Konvertierungsmethoden aus Core Reflection API-Objekten, z java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect. B. .

Wie Klassen und Zeichenfolgen können Methodenhandles, die barrierefreien Feldern, Methoden und Konstruktoren entsprechen, auch direkt im Konstantenpool einer Klassendatei als Konstanten dargestellt werden, die von ldc Bytecodes geladen werden sollen. Ein neuer Typ von Konstantenpooleintrag , CONSTANT_MethodHandlebezieht sich direkt auf einen zugeordneten CONSTANT_Methodref, CONSTANT_InterfaceMethodrefoder CONSTANT_Fieldref konstanten Pooleintrag. (Ausführliche Informationen zu Methodenhandlekonstanten finden Sie in den Abschnitten 4.4.8 und 5.4.3.5 der Java Virtual Machine-Spezifikation.)

Methodenhandles, die von Nachschlagevorgängen oder konstanten Ladevorgängen von Methoden oder Konstruktoren mit dem Variablen arity-Modifizierer bit (0x0080) erzeugt werden, weisen eine entsprechende Variable arity auf, als ob sie mit Hilfe von #asVarargsCollector asVarargsCollectordefiniert würden.

Ein Methodenverweis kann auf eine statische oder nicht statische Methode verweisen. Im nicht statischen Fall enthält der Handle-Typ der Methode ein explizites Empfängerargument, das vor allen anderen Argumenten vorangestellt wird. Im Typ des Methodenhandles wird das anfängliche Empfängerargument gemäß der Klasse eingegeben, unter der die Methode ursprünglich angefordert wurde. (Wenn z. B. ein nicht statisches Methodenhandle über ldcabgerufen wird, ist der Typ des Empfängers die Klasse, die im Konstantenpooleintrag benannt ist.)

Methodenhandlekonstanten unterliegen denselben Linkzeitzugriffsprüfungen mit den entsprechenden Bytecodeanweisungen, und die ldc Anweisung löst entsprechende Verknüpfungsfehler aus, wenn das Bytecodeverhalten solche Fehler auslöst.

Als Folge davon ist der Zugriff auf geschützte Member nur auf Empfänger der Zugriffsklasse oder einer ihrer Unterklassen beschränkt, und die zugreifende Klasse muss wiederum eine Unterklasse (oder gleichgeordnete Paket) der definierenden Klasse des geschützten Elements sein. Wenn ein Methodenverweis auf eine geschützte nicht statische Methode oder ein geschütztes Feld einer Klasse außerhalb des aktuellen Pakets verweist, wird das Empfängerargument auf den Typ der zugreifenden Klasse beschränkt.

Wenn ein Methodenhandle für eine virtuelle Methode aufgerufen wird, wird die Methode immer im Empfänger (d. a. das erste Argument) gesucht.

Ein nicht virtueller Methodenhandle für eine bestimmte Implementierung virtueller Methoden kann auch erstellt werden. Diese führen keine virtuelle Suche basierend auf dem Empfängertyp durch. Ein solcher Methodenhandle simuliert die Auswirkung einer invokespecial Anweisung auf dieselbe Methode.

<h1>Verwendungsbeispiele</h1> Hier sind einige Verwendungsbeispiele: <blockquote>

{@code
            Object x, y; String s; int i;
            MethodType mt; MethodHandle mh;
            MethodHandles.Lookup lookup = MethodHandles.lookup();
            // mt is (char,char)String
            mt = MethodType.methodType(String.class, char.class, char.class);
            mh = lookup.findVirtual(String.class, "replace", mt);
            s = (String) mh.invokeExact("daddy",'d','n');
            // invokeExact(Ljava/lang/String;CC)Ljava/lang/String;
            assertEquals(s, "nanny");
            // weakly typed invocation (using MHs.invoke)
            s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
            assertEquals(s, "savvy");
            // mt is (Object[])List
            mt = MethodType.methodType(java.util.List.class, Object[].class);
            mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
            assert(mh.isVarargsCollector());
            x = mh.invoke("one", "two");
            // invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
            assertEquals(x, java.util.Arrays.asList("one","two"));
            // mt is (Object,Object,Object)Object
            mt = MethodType.genericMethodType(3);
            mh = mh.asType(mt);
            x = mh.invokeExact((Object)1, (Object)2, (Object)3);
            // invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
            assertEquals(x, java.util.Arrays.asList(1,2,3));
            // mt is ()int
            mt = MethodType.methodType(int.class);
            mh = lookup.findVirtual(java.util.List.class, "size", mt);
            i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));
            // invokeExact(Ljava/util/List;)I
            assert(i == 3);
            mt = MethodType.methodType(void.class, String.class);
            mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
            mh.invokeExact(System.out, "Hello, world.");
            // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
            }

</blockquote> Jeder der obigen Aufrufe invokeExact von oder plain invoke generiert eine einzelne invokevirtuelle Anweisung mit dem symbolischen Typdeskriptor, der im folgenden Kommentar angegeben ist. In diesen Beispielen wird davon ausgegangen, dass die Hilfsmethode assertEquals eine Methode ist, die ihre Argumente aufruft java.util.Objects#equals(Object,Object) Objects.equals und behauptet, dass das Ergebnis wahr ist.

<h1>Ausnahmen</h1> Die Methoden invokeExact und invoke werden deklariert, um auszulösen java.lang.Throwable Throwable, was bedeutet, dass es keine statische Einschränkung dafür gibt, was ein Methodenhandle auslösen kann. Da die JVM nicht zwischen aktivierten und nicht überprüften Ausnahmen unterscheidet (außer natürlich durch ihre Klasse), gibt es keine besondere Auswirkung auf bytecode-Shape, wenn überprüfte Ausnahmen für Methodenhandleaufrufe zugewiesen werden. Aber im Java-Quellcode müssen Methoden, die Methodenhandle-Aufrufe ausführen, entweder explizit auslösen Throwableoder müssen alle Throwables lokal abfangen, nur diejenigen, die im Kontext legal sind, und umschließen, die illegal sind.

<h1>"sigpoly">Signature polymorphism</h1> Auf das ungewöhnliche Kompilierungs- und Verknüpfungsverhalten von invokeExact und plain invoke wird durch den Begriff <em>signature polymorphism</em> verwiesen. Wie in der Java-Sprachspezifikation definiert, ist eine polymorphe Signaturmethode, die mit einer vielzahl von Aufrufsignaturen und Rückgabetypen arbeiten kann.

Im Quellcode wird ein Aufruf einer polymorphen Signaturmethode kompiliert, unabhängig von der angeforderten Symboltypdeskriptor. Wie üblich gibt der Java-Compiler eine invokevirtual Anweisung mit dem angegebenen symbolischen Typdeskriptor für die benannte Methode aus. Der ungewöhnliche Teil ist, dass der symbolische Typdeskriptor vom tatsächlichen Argument und rückgabetypen abgeleitet wird, nicht von der Methodendeklaration.

Wenn die JVM Bytecode verarbeitet, der polymorphe Signature-Aufrufe enthält, wird jeder solche Aufruf erfolgreich verknüpft, unabhängig von seinem symbolischen Typdeskriptor. (Um die Typsicherheit zu gewährleisten, schützt die JVM solche Aufrufe mit geeigneten dynamischen Typprüfungen, wie an anderer Stelle beschrieben.)

Bytecodegeneratoren, einschließlich des Compiler-Back-End, sind erforderlich, um nicht übersetzte symbolische Typdeskriptoren für diese Methoden auszugeben. Tools, die die symbolische Verknüpfung bestimmen, sind erforderlich, um solche nicht übersetzten Deskriptoren zu akzeptieren, ohne Verknüpfungsfehler zu melden.

<h1>Interoperation zwischen Methodenhandles und der Core Reflection-API</h1> Mithilfe von Factorymethoden in der API kann ein beliebiger Klassenmember, der java.lang.invoke.MethodHandles.Lookup Lookup durch ein Core Reflection-API-Objekt dargestellt wird, in ein verhalten gleichwertiges Methodenhandle konvertiert werden. Beispielsweise kann ein Reflektieren java.lang.reflect.Method Method mithilfe java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflectvon in ein Methodenhandle konvertiert werden. Die resultierenden Methodenhandles bieten in der Regel einen direkteren und effizienteren Zugriff auf die zugrunde liegenden Klassenmember.

Wenn die Core Reflection-API verwendet wird, um die polymorphen Methoden invokeExact der Signatur oder die einfache invoke Methode in dieser Klasse anzuzeigen, werden diese als gewöhnliche nicht polymorphe Methoden angezeigt. Ihr reflektierendes Aussehen, wie von java.lang.Class#getDeclaredMethod Class.getDeclaredMethodbetrachtet, bleibt von ihrer speziellen status in dieser API unberührt. Meldet beispielsweise genau die Modifiziererbits, java.lang.reflect.Method#getModifiers Method.getModifiers die für jede ähnlich deklarierte Methode erforderlich sind, einschließlich in diesem Fall native und varargs Bits.

Wie bei jeder reflektierten Methode können diese Methoden (wenn sie reflektiert werden) über java.lang.reflect.Method#invoke java.lang.reflect.Method.invokeaufgerufen werden. Solche reflektierenden Aufrufe führen jedoch nicht zu Methodenhandleaufrufen. Wenn ein solcher Aufruf das erforderliche Argument (ein einzelnes argument vom Typ Object[]) übergeben hat, ignoriert das Argument und löst ein aus UnsupportedOperationException.

Da invokevirtual Anweisungen Methodenhandles unter jedem symbolischen Typdeskriptor nativ aufrufen können, steht diese reflektierende Ansicht in Konflikt mit der normalen Darstellung dieser Methoden über Bytecodes. Daher können diese beiden nativen Methoden, wenn sie von Class.getDeclaredMethodreflektiert betrachtet werden, nur als Platzhalter betrachtet werden.

Um eine Aufrufmethode für einen bestimmten Typdeskriptor abzurufen, verwenden Sie java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvokeroder java.lang.invoke.MethodHandles#invoker MethodHandles.invoker. Die java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual API kann auch ein Methodenhandle zurückgeben, um für jeden angegebenen Typdeskriptor auf- oder einfach invokeaufzurufeninvokeExact.

<h1>Interoperation zwischen Methodenhandles und Java generics</h1> Ein Methodenhandle kann für eine Methode, einen Konstruktor oder ein Feld abgerufen werden, das mit generischen Java-Typen deklariert ist. Wie bei der Core Reflection-API wird der Typ des Methodenhandles aus dem Löschen des Typs auf Quellebene erstellt. Wenn ein Methodenhandle aufgerufen wird, können die Typen seiner Argumente oder der Rückgabewert-Casttyp generische Typen oder Typinstanzen sein. In diesem Fall ersetzt der Compiler diese Typen durch ihre Löschungen, wenn er den symbolischen Typdeskriptor für die invokevirtual Anweisung erstellt.

Methodenhandles stellen ihre funktionsähnlichen Typen nicht in Bezug auf java-parametrisierte (generische) Typen dar, da es drei Übereinstimmungen zwischen funktionsähnlichen Typen und parametrisierten Java-Typen gibt. <ul><li>Methodentypen reichen über alle möglichen Aritäten, von keinen Argumenten bis zur maximalen Anzahl zulässiger Argumente. Generika sind nicht variadisch und können dies daher nicht darstellen.</li><li>Methodentypen können Argumente von primitiven Typen angeben, über die generische Java-Typen nicht reichen können.</li><li>Funktionen höherer Reihenfolge als Methodenhandles (Kombinatoren) sind häufig für eine Vielzahl von Funktionstypen generisch, einschließlich der Funktionen mehrerer Aritäten. Es ist unmöglich, eine solche Generizität mit einem Java-Typparameter darzustellen.</li></ul>

<h1>"maxarity">Arity limits</h1> Die JVM legt für alle Methoden und Konstruktoren jeglicher Art eine absolute Grenze von 255 gestapelten Argumenten fest. Dieser Grenzwert kann in bestimmten Fällen restriktiver erscheinen: <ul><li>A long oder double Argumentanzahl (aus Gründen der Aritätsgrenzwerte) als zwei Argumentslots. <li>Eine nicht statische Methode verbraucht ein zusätzliches Argument für das Objekt, für das die Methode aufgerufen wird. <li>Ein Konstruktor verbraucht ein zusätzliches Argument für das Objekt, das erstellt wird. <li>Da ein Methodenhandle’ die Methode invoke (oder eine andere signatur-polymorphe Methode) ist nicht virtualisiert, sie verwendet ein zusätzliches Argument für das Methodenhandle selbst, zusätzlich zu jedem nicht virtuellen Empfängerobjekt. </ul> Diese Grenzwerte implizieren, dass bestimmte Methodenhandles nur aufgrund des JVM-Grenzwerts für gestapelte Argumente nicht erstellt werden können. Wenn beispielsweise eine statische JVM-Methode genau 255 Argumente akzeptiert, kann kein Methodenhandle für sie erstellt werden. Versuche, Methodenhandles mit unmöglichen Methodentypen zu erstellen, führen zu einem IllegalArgumentException. Insbesondere wird eine Methode’ Der Typ darf keine Arität von exakt 255 aufweisen.

Java-Dokumentation für java.lang.invoke.MethodHandle.

Teile dieser Seite sind Änderungen, die auf Arbeiten basieren, die vom Android Open Source Project erstellt und freigegeben wurden und gemäß den In der Attribution License beschriebenen Begriffen verwendet werden.

Konstruktoren

MethodHandle(IntPtr, JniHandleOwnership)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

Eigenschaften

Class

Gibt die Laufzeitklasse dieses Objectzurück.

(Geerbt von Object)
Handle

Das Handle für die zugrunde liegende Android-instance.

(Geerbt von Object)
IsVarargsCollector

Bestimmt, ob dieses Methodenhandle #asVarargsCollector Aufrufe von Variablen unterstützt.

JniIdentityHashCode

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
JniPeerMembers

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

PeerReference

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
ThresholdClass

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

ThresholdType

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

Methoden

AsCollector(Class, Int32)

Erstellt ein <>Em-Array-Collecting</em-Methodenhandle>, das eine bestimmte Anzahl nachgestellter Positionsargumente akzeptiert und in einem Arrayargument sammelt.

AsCollector(Int32, Class, Int32)

Erstellt ein Handle für eine <em>array-collecting</em-Methode> , die eine bestimmte Anzahl von Positionsargumenten ab einer bestimmten Position akzeptiert und in einem Arrayargument sammelt.

AsFixedArity()

Stellt ein <>festes Arity</em-Methodenhandle> her, das andernfalls dem aktuellen Methodenhandle entspricht.

AsSpreader(Class, Int32)

Erstellt ein Handle der <em>array-spread</em-Methode> , das ein nachfolgendes Arrayargument akzeptiert und dessen Elemente als Positionsargumente verteilt.

AsSpreader(Int32, Class, Int32)

Erstellt ein <>Em-Array-Spread</em-Methodenhandle>, das ein Arrayargument an einer bestimmten Position akzeptiert und seine Elemente als Positionsargumente anstelle des Arrays verteilt.

AsType(MethodType)

Erzeugt ein Adaptermethodenhandle, das den Typ des aktuellen Methodenhandles an einen neuen Typ anpasst.

AsVarargsCollector(Class)

Stellt einen <em-Variablen>arity</em-Adapter> her, der eine beliebige Anzahl von nachgestellten Positionsargumenten akzeptieren und in einem Arrayargument sammeln kann.

BindTo(Object)

Bindet einen Wert x an das erste Argument eines Methodenhandles, ohne ihn aufrufen zu müssen.

Clone()

Erstellt und gibt eine Kopie dieses Objekts zurück.

(Geerbt von Object)
Dispose()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
Dispose(Boolean)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
Equals(Object)

Gibt an, ob ein anderes Objekt "gleich" diesem objekt ist.

(Geerbt von Object)
GetHashCode()

Gibt einen Hashcodewert für das Objekt zurück.

(Geerbt von Object)
Invoke(Object[])

Ruft das Methodenhandle auf, lässt jeden Aufrufertypdeskriptor zu und führt optional Konvertierungen für Argumente und Rückgabewerte durch.

InvokeExact(Object[])

Ruft das Methodenhandle auf, sodass jeder Aufrufertypdeskriptor zugelassen wird, aber eine genaue Typüberstimmung erforderlich ist.

InvokeWithArguments(IList<Object>)

Führt einen Variablenaritätsaufruf aus und übergibt die Argumente im angegebenen Array an das Methodenhandle, als ob über eine Ungenaue #invoke invoke von einer Aufrufwebsite, die nur den Typ Objecterwähnt, und dessen Arität die Länge des Argumentarrays ist.

InvokeWithArguments(Object[])

Führt einen Variablenaritätsaufruf aus und übergibt die Argumente in der angegebenen Liste an das Methodenhandle, als ob über eine Ungenaue #invoke invoke von einer Aufrufwebsite, die nur den Typ Objecterwähnt, und deren Arität die Länge der Argumentliste ist.

JavaFinalize()

Wird vom Garbage Collector für ein Objekt aufgerufen, wenn die Garbage Collection feststellt, dass keine Verweise mehr auf das Objekt vorhanden sind.

(Geerbt von Object)
Notify()

Aktiviert einen einzelnen Thread, der auf den Monitor dieses Objekts wartet.

(Geerbt von Object)
NotifyAll()

Aktiviert alle Threads, die auf den Monitor dieses Objekts warten.

(Geerbt von Object)
SetHandle(IntPtr, JniHandleOwnership)

Legt die Handle-Eigenschaft fest.

(Geerbt von Object)
ToArray<T>()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
ToString()

Gibt eine Zeichenfolgendarstellung des Objekts zurück.

(Geerbt von Object)
Type()

Meldet den Typ dieses Methodenhandles.

UnregisterFromRuntime()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
Wait()

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch <>Benachrichtigung</em> oder <em>interrupted</em>.

(Geerbt von Object)
Wait(Int64)

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch>< Benachrichtigung</em> oder <em>interrupted</em>, oder bis eine bestimmte Menge an Echtzeit verstrichen ist.

(Geerbt von Object)
Wait(Int64, Int32)

Bewirkt, dass der aktuelle Thread wartet, bis er aktiviert ist, in der Regel durch>< Benachrichtigung</em> oder <em>interrupted</em>, oder bis eine bestimmte Menge an Echtzeit verstrichen ist.

(Geerbt von Object)
WithVarargs(Boolean)

Passt dieses Methodenhandle an, um #asVarargsCollector variablen Arität zu sein, wenn das boolesche Flag true ist, andernfalls #asFixedArity feste Arität.

Explizite Schnittstellenimplementierungen

IJavaPeerable.Disposed()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.DisposeUnlessReferenced()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.Finalized()

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.JniManagedPeerState

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

(Geerbt von Object)

Erweiterungsmethoden

JavaCast<TResult>(IJavaObject)

Führt eine Typkonvertierung mit Überprüfung der Android-Laufzeit aus.

JavaCast<TResult>(IJavaObject)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

GetJniTypeName(IJavaPeerable)

Ein Methodenhandle ist ein typisierter, direkt ausführbarer Verweis auf eine zugrunde liegende Methode, einen Konstruktor, ein Feld oder einen ähnlichen Vorgang auf niedriger Ebene mit optionalen Transformationen von Argumenten oder Rückgabewerten.

Gilt für: