2012-01-11 23 views
41

Sto studiando nuove funzionalità di JDK 1.7 e non riesco proprio a capire a cosa serve MethodHandle? Comprendo l'invocazione (diretta) del metodo statico (e l'uso dell'API di Core Reflection che è semplice in questo caso). Comprendo anche l'invocazione (diretta) del metodo virtuale (non statico, non finale) (e l'uso dell'API Core Reflection che richiede di passare attraverso la gerarchia della classe obj.getClass().getSuperclass()). L'invocazione del metodo non virtuale può essere trattata come caso speciale del precedente.MethodHandle - Di cosa si tratta?

Sì, sono a conoscenza del problema di sovraccarico. Se vuoi invocare il metodo devi fornire la firma esatta. Non è possibile controllare il metodo sovraccarico in modo semplice.

Ma di cosa parla MethodHandle? L'API di Reflection consente di "guardare" gli interni dell'oggetto senza alcuna presunzione (come implementata l'interfaccia). È possibile ispezionare l'oggetto per qualche scopo. Ma cos'è progettato anche MethodHandle? Perché e quando dovrei usarlo?

UPDATE: Sto leggendo ora questo articolo http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html. In base a ciò, l'obiettivo principale è semplificare la vita dei linguaggi di script che vengono eseguiti in cima a JVM e non per Java Language stesso.

UPDATE-2: finisco di leggere il link qui sopra, alcuni citazione da lì:

La JVM sta per essere la migliore macchina virtuale per la creazione di linguaggi dinamici, perché già è un linguaggio dinamico VM. E InvokeDynamic, promuovendo linguaggi dinamici per cittadini JVM di prima classe, lo dimostrerà.

L'uso della riflessione per invocare metodi funziona alla grande ... tranne per alcuni problemi. Gli oggetti metodo devono essere recuperati da un tipo specifico e non possono essere creati in modo generale. < ...>

... l'invocazione riflessa è molto più lenta dell'invocazione diretta. Nel corso degli anni, la JVM è diventata davvero brava a rendere veloce l'invocazione riflessa. Le moderne JVM generano effettivamente un po 'di codice dietro le quinte per evitare una gran parte delle vecchie JVM gestite. Ma la semplice verità è che l'accesso riflesso attraverso qualsiasi numero di livelli sarà sempre più lento di una chiamata diretta, in parte perché il metodo "invoke" completamente generato deve controllare e ricontrollare il tipo di ricevitore, i tipi di argomenti, la visibilità e altri dettagli, ma anche perché gli argomenti devono essere tutti oggetti (quindi le primitive ricevono oggetti in box) e devono essere forniti come una matrice per coprire tutte le possibili entità (in modo che gli argomenti vengano ordinati in serie).

La differenza di prestazioni potrebbe non essere importante per una libreria che esegue alcune chiamate riflesse, soprattutto se tali chiamate servono principalmente a configurare dinamicamente una struttura statica in memoria rispetto alla quale è possibile effettuare chiamate normali. Ma in un linguaggio dinamico, in cui ogni chiamata deve utilizzare questi meccanismi, si tratta di un grave colpo di performance.

http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html

Così, per programmatori Java è essenzialmente inutile. Ho ragione? Da questo punto di vista, può essere considerato solo come un modo alternativo per l'API Core Reflection.

+0

No, assolutamente no. Quel post ha più di 3 anni. Un gran numero di sviluppatori di frameworks stanno osservando da vicino MH e invocati dinamici e modi per usarli per aiutare gli sviluppatori. – kittylyst

+0

Potete fornire un esempio di tale uso? Cosa è possibile fare con MethodHandle che è impossibile fare con l'API Core Reflection? – alexsmail

+1

Ad esempio, l'interazione con un gestore della sicurezza. setAccessible() ti ucciderà sotto un gestore della sicurezza, mentre il meccanismo di ricerca è completamente sicuro. La ricerca consente inoltre di creare un MH in un contesto in cui è possibile visualizzarlo e quindi passare il riferimento a contesti non privilegiati. – kittylyst

risposta

29

Precursore di Java 8 che fornisce supporto linguistico per MethodHandles. Sarai in grado di fare riferimento a un metodo direttamente e MethodHandles lo supporterà.

Che cosa si può fare con MethodHandles è metodi di curry, modificare i tipi di parametri e modificare il loro ordine.

Method Handles può gestire entrambi i metodi e campi.

Un altro trucco che MethodHandles fanno è utilizzare primitivi diretta (piuttosto che attraverso gli involucri)

MethodHandles può essere più veloce rispetto all'utilizzo di riflessione in quanto v'è un sostegno più diretto nella JVM per esempio possono essere inline. Usa la nuova istruzione invokedynamic.

+6

in Inoltre, le stacktraces quando si invocano sono molto più belle di quelle con la riflessione: come svantaggio, non si può chiamare un metodo tramite riflessione (ma viceversa) – mihi

+8

'MethodHandle's non usa l'istruzione invokedynamic ma c'è una relazione l'altra modo: l'istruzione invokedynamic si basa pesantemente su 'MethodHandle's. – Holger

+2

@Peter Cosa intendi esattamente per" Un altro trucco che MethodHandles do usa primitive direct (piuttosto che via wrappers) "? – Geek

10

java.lang.reflect.Method è relativamente lento e costoso in termini di memoria. Si suppone che i manici di metodo siano un modo "leggero" di passare i puntatori a funzioni che la JVM ha la possibilità di ottimizzare. A partire dal metodo JDK8, gli handle non sono ottimizzati in modo ottimale e probabilmente i lambda saranno inizialmente implementati in termini di classi (come le classi interne).

+0

@tackline, so che 'java.lang.reflect.Method' è relativamente lento.Ho visto anche alcune statistiche che mostrano che' MehodHandle' non è Il motivo principale sono le prestazioni? Che cosa sta facendo Lambda in Java? Il Lambda-calculus è un approccio totalmente diverso alla programmazione ... – alexsmail

+0

@tackline, per favore guarda il mio aggiornamento sopra. – alexsmail

+0

un altro aggiornamento aggiunto – alexsmail

7

Pensa a MethodHandle come un modo moderno, più flessibile e più tipicamente di riflettere.

Attualmente è nelle prime fasi del suo ciclo di vita, ma nel tempo ha il potenziale per essere ottimizzato per diventare più veloce della riflessione - al punto che può diventare veloce come una normale chiamata di metodo.

+0

È contro la filosofia java di base dare solo un modo possibile per fare le cose per il programmatore Java. So che l'introduzione di alcune funzionalità in JDK 1.5 le ha cambiate, ma le funzionalità di JDK 1.5 sono state utili per Java Programmer (beh, lo so, alcune sono contestate), la funzione MethodHandle non è utile per quanto vedo ora per gli sviluppatori Java regolari. – alexsmail

Problemi correlati