2012-01-11 22 views
41

Estoy estudiando nuevas funciones de JDK 1.7 y simplemente no puedo obtenerlo ¿para qué está diseñado MethodHandle? Entiendo la invocación (directa) del método estático (y el uso de Core Reflection API que es sencillo en este caso). También entiendo la invocación (directa) del método virtual (no estático, no final) (y el uso de Core Reflection API que requiere pasar por la jerarquía de la clase obj.getClass().getSuperclass()). La invocación de un método no virtual puede tratarse como un caso especial del anterior.MethodHandle: ¿de qué se trata?

Sí, sé que hay un problema con la sobrecarga. Si desea invocar el método, debe proporcionar la firma exacta. No se puede verificar el método sobrecargado de manera fácil.

Pero, ¿qué es MethodHandle? Reflection API le permite "mirar" las partes internas del objeto sin ninguna presunción (como la interfaz implementada). Puedes inspeccionar el objeto por algún motivo. Pero, ¿qué está diseñado MethodHandle también? ¿Por qué y cuándo debería usarlo?

ACTUALIZACIÓN: Estoy leyendo ahora este artículo http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html. Según él, el objetivo principal es simplificar la vida de los lenguajes de script que se ejecuta encima de JVM, y no para el lenguaje Java en sí mismo.

ACTUALIZACIÓN-2: termino de leer el enlace anterior, algunos de cotización a partir de ahí:

La JVM va a ser la mejor máquina virtual para la construcción de lenguajes dinámicos, porque ya es un lenguaje dinámico VM. E InvokeDynamic, al promover lenguajes dinámicos para los ciudadanos JVM de primera clase, lo demostrará.

El uso de la reflexión para invocar métodos funciona muy bien ... excepto por unos pocos problemas. Los objetos de método se deben recuperar de un tipo específico y no se pueden crear de forma general. < ...>

... la invocación reflejada es mucho más lenta que la invocación directa. Con los años, la JVM se ha vuelto realmente buena para hacer que la invocación reflejada sea rápida. Las JVM modernas en realidad generan un montón de código detrás de las escenas para evitar que se solucione una gran parte de las antiguas JVM. Pero la verdad es que el acceso reflejado a través de cualquier cantidad de capas siempre será más lento que una llamada directa, en parte porque el método "invocar" completamente generizado debe verificar y volver a verificar el tipo de receptor, los tipos de argumentos, la visibilidad y otros detalles, pero también porque todos los argumentos deben ser objetos (para que las primitivas tengan un recuadro de objeto) y se deben proporcionar como una matriz para cubrir todas las aries posibles (de modo que los argumentos se obtengan en una matriz).

La diferencia en el rendimiento puede no ser importante para una biblioteca que realiza algunas llamadas reflejadas, especialmente si esas llamadas son principalmente para configurar dinámicamente una estructura estática en memoria contra la cual puede realizar llamadas normales. Pero en un lenguaje dinámico, donde cada llamada debe usar estos mecanismos, es un golpe de rendimiento severo.

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

Por lo tanto, para el programador de Java que es esencialmente inútil. ¿Estoy en lo cierto? Desde este punto de vista, solo se puede considerar como una forma alternativa para Core Reflection API.

+0

No, absolutamente no. Esa publicación tiene más de 3 años. Un gran número de desarrolladores de frameworks están mirando de cerca a MH e invocan dinámica y formas de usarlos para ayudar a los desarrolladores. – kittylyst

+0

¿Puedes darnos un ejemplo de tal uso? ¿Qué se puede hacer con MethodHandle que es imposible de hacer con Core Reflection API? – alexsmail

+1

Por ejemplo, interactuando con un administrador de seguridad. setAccessible() lo matará bajo un administrador de seguridad, mientras que el mecanismo de búsqueda es completamente seguro. La búsqueda también le permite crear un MH dentro de un contexto donde puede verlo, y luego pasar la referencia a contextos sin privilegios. – kittylyst

Respuesta

29

Es precursor de Java 8 que proporciona soporte de idiomas para MethodHandles. Podrá consultar un método directamente y MethodHandles lo admitirá.

Lo que puedes hacer con MethodHandles son los métodos de curry, cambiar los tipos de parámetros y cambiar su orden.

Método Los identificadores pueden manejar métodos y campos.

Otro truco, que MethodHandles hacen es utilizar primitivas directa (en vez de a través de las envolturas)

MethodHandles puede ser más rápido que utilizando la reflexión ya que hay un apoyo más directo en la JVM por ejemplo pueden ser inline. Utiliza la nueva instrucción invokedynamic.

+6

in Además, las stacktraces al hacer la invocación son mucho más agradables que con la reflexión. Como desventaja, no se puede llamar a un método handle a través de la reflexión (sino al revés) – mihi

+8

'MethodHandle's no usa la instrucción invocada dinámica. Pero hay una relación con el otro manera: la instrucción invocada dinámica se basa en gran medida en 'MethodHandle's. – Holger

+2

@Peter ¿Qué quiere decir exactamente con" Otro truco que MethodHandles do es utilizar primitivo directo (en lugar de a través de envoltorios) "? – Geek

10

java.lang.reflect.Method es relativamente lento y costoso en términos de memoria. Se supone que los identificadores de método son una forma "ligera" de pasar punteros a funciones que la JVM tiene la posibilidad de optimizar. A partir del método JDK8, los identificadores no están tan bien optimizados, y es probable que los lambdas se implementen inicialmente en términos de clases (como las clases internas).

+0

@tackline, sé que 'java.lang.reflect.Method' es relativamente lento. También vi algunas estadísticas que muestran que' MehodHandle' no es tan rápido. Entonces, ¿la razón principal es el rendimiento? ¿Qué está haciendo lambda en java? Lambda-cálculo es un enfoque totalmente diferente a la programación ... – alexsmail

+0

@tackline, mira mi actualización anterior. – alexsmail

+0

una actualización más agregó – alexsmail

7

Piense en MethodHandle como una forma moderna, más flexible y más segura de hacer reflexiones.

Actualmente se encuentra en las primeras etapas de su ciclo de vida, pero con el tiempo tiene el potencial de optimizarse para convertirse en algo más rápido que la reflexión, hasta el punto de que puede llegar a ser tan rápido como una llamada a método normal.

+0

Está en contra de la filosofía básica de java dar solo una forma posible para hacer cosas para el programador de Java. Sé que la introducción de algunas características en JDK 1.5 las modificó, pero las funciones en JDK 1.5 fueron útiles para el Programador Java (bueno, lo sé, algunas están en disputa), la función MethodHandle no es útil hasta ahora para el Desarrollador Java normal. – alexsmail

Cuestiones relacionadas