Я изучаю новые возможности JDK 1.7, и я просто не могу понять, для чего предназначен MethodHandle? Я понимаю (прямой) вызов статического метода (и использование Core Reflection API, который в этом случае является простым). Я также понимаю (прямой) вызов виртуального метода (нестатического, нефинального) (и использование API Core Reflection, требующего прохождения иерархии класса obj.getClass().getSuperclass()
). Вызов не виртуального метода можно рассматривать как частный случай первого.MethodHandle - В чем дело?
Да, я знаю, что есть проблема с перегрузкой. Если вы хотите вызвать метод, вы должны указать точную подпись. Вы не можете легко проверить перегруженный метод.
Но что такое методHandle? API Reflection позволяет вам «просматривать» внутренние объекты без каких-либо предварительных допущений (например, реализованный интерфейс). Вы можете осмотреть объект для какой-либо цели. Но что же такое MethodHandle? Почему и когда я должен его использовать?
ОБНОВЛЕНИЕ: Я читаю сейчас этот http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html артикул. В соответствии с этим главная цель - упростить жизнь для языков сценариев, которые работают поверх JVM, а не для самого языка Java.
ДОПОЛНЕНО-2: я закончу читать по ссылке выше, некоторые цитаты оттуда:
Виртуальная машина Java будет лучшим VM для построения динамических языков, потому что уже есть динамический язык VM. И InvokeDynamic, продвигая динамические языки для первоклассных граждан JVM, докажет это.
Использование отражения для вызова методов отлично работает ... за исключением нескольких проблем. Объекты метода должны извлекаться из определенного типа и не могут быть созданы в общем виде. < ...>
... отраженный вызов намного медленнее, чем прямой вызов. На протяжении многих лет JVM отлично справлялся с тем, чтобы сделать обратный вызов быстрым. Современные JVM на самом деле генерируют кучу кода за кулисами, чтобы избежать значительной части старых JVM. Но простая истина заключается в том, что отраженный доступ через любое количество уровней всегда будет медленнее прямого вызова, частично потому, что полностью генерализованный метод «invoke» должен проверять и повторно проверять тип приемника, типы аргументов, видимость и другие данные, но также потому, что аргументы должны быть объектами (поэтому примитивы получают объект-бокс) и должны быть предоставлены в виде массива для охвата всех возможных явлений (поэтому аргументы получают массив-boxed).
Разница в производительности может не иметь значения для библиотеки, выполняющей несколько отраженных вызовов, особенно если эти вызовы в основном предназначены для динамической настройки статической структуры в памяти, с которой она может выполнять обычные вызовы. Но на динамическом языке, где каждый вызов должен использовать эти механизмы, это серьезный удар по производительности.
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
Таким образом, для Java программиста это, по сути бесполезно. Я прав? С этой точки зрения, это можно рассматривать только как альтернативный способ для Core Reflection API.
Нет, абсолютно нет. Эта должность старше 3 лет. Многие разработчики фреймворков внимательно изучают MH и invokedynamic, а также способы их использования, чтобы помочь разработчикам. – kittylyst
Можете ли вы привести пример такого использования? Что можно сделать с MethodHandle, что невозможно сделать с Core Reflection API? – alexsmail
Например, взаимодействие с менеджером безопасности. setAccessible() убьет вас под менеджером безопасности, тогда как механизм Lookup полностью безопасен. Lookup также позволяет создавать MH в контексте, где вы можете его увидеть, а затем передать ссылку на непривилегированные контексты. – kittylyst