MethodHandle - О чем все это? - PullRequest
       63

MethodHandle - О чем все это?

46 голосов
/ 11 января 2012

Я изучаю новые возможности JDK 1.7 и просто не могу понять, для чего предназначен метод MethodHandle?Я понимаю (прямой) вызов статического метода (и использование Core Reflection API, что в данном случае просто).Я также понимаю (прямой) вызов виртуального метода (нестатический, не финальный) (и использование Core Reflection API, которое требует прохождения иерархии класса obj.getClass().getSuperclass()).Вызов не виртуального метода может рассматриваться как частный случай предыдущего.

Да, я знаю, что существует проблема с перегрузкой.Если вы хотите вызвать метод, вы должны указать точную подпись.Вы не можете проверить перегруженный метод простым способом.

Но что такое MethodHandle?Reflection API позволяет «смотреть» на внутренние объекты объекта без каких-либо предварительных предположений (например, реализован интерфейс).Вы можете осмотреть объект для какой-то цели.Но для чего предназначен MethodHandle?Почему и когда я должен его использовать?

ОБНОВЛЕНИЕ: Я сейчас читаю эту http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html статью.В соответствии с этим основная цель - упростить жизнь для языков сценариев, работающих на JVM, а не для самого языка Java.

UPDATE-2: Я заканчиваю читать ссылку вышенекоторые цитаты оттуда:

JVM станет лучшей виртуальной машиной для построения динамических языков, поскольку она уже является виртуальной языковой динамической виртуальной машиной.И InvokeDynamic, продвигая динамические языки для первоклассных граждан JVM, докажет это.

Использование рефлексии для вызова методов прекрасно работает ... за исключением нескольких проблем.Объекты метода должны быть получены из определенного типа и не могут быть созданы общим способом. <...>

... отраженный вызов намного медленнее, чем прямой вызов.За прошедшие годы JVM действительно хорошо справилась с быстрым отражением вызовов.Современные JVM на самом деле генерируют кучу кода за кулисами, чтобы избежать значительной части накладных расходов, с которыми сталкиваются старые JVM.Но простая истина заключается в том, что отраженный доступ через любое количество слоев всегда будет медленнее, чем прямой вызов, отчасти потому, что полностью обобщенный метод invoke должен проверять и перепроверять тип получателя, типы аргументов, видимость и другие детали, нотакже потому, что все аргументы должны быть объектами (таким образом, примитивы становятся объектно-упакованными) и должны предоставляться в виде массива, чтобы покрыть все возможные арности (поэтому аргументы должны быть упакованы в массив).

Разница в производительности может не иметь значения длябиблиотека выполняет несколько отраженных вызовов, особенно если эти вызовы в основном предназначены для динамической настройки статической структуры в памяти, для которой она может выполнять обычные вызовы.Но в динамическом языке, где каждый вызов должен использовать эти механизмы, это серьезный удар по производительности.

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

Так что для программиста на Java это практически бесполезно.Я прав?С этой точки зрения, его можно рассматривать только как альтернативный способ для Core Reflection API.

Ответы [ 3 ]

33 голосов
/ 11 января 2012

То, что вы можете сделать с MethodHandles, это методы карри, изменить типы параметров и изменить их порядок.

Методы могут обрабатывать как методы, так и поля.

Еще один трюк, который делают MethodHandles, - это использование прямого примитива (а не через обертки)

MethodHandles может быть быстрее, чем при использовании отражения, поскольку в JVM есть более прямая поддержка, например, они могут быть встроенными Он использует новую команду invokedynamic.

11 голосов
/ 11 января 2012

java.lang.reflect.Method относительно медленный и дорогой с точки зрения памяти. Предполагается, что дескрипторы методов являются «облегченным» способом передачи указателей на функции, которые JVM имеет возможность оптимизировать. Что касается дескрипторов методов JDK8, то они не так хорошо оптимизированы, и лямбды, вероятно, будут изначально реализованы в терминах классов (как и внутренние классы).

9 голосов
/ 11 января 2012

Думайте о MethodHandle как о современном, более гибком, более безопасном способе отражения.

В настоящее время он находится на ранних стадиях своего жизненного цикла - но со временем он может быть оптимизирован, чтобы стать быстрее, чем рефлексия, - настолько, что он может стать таким же быстрым, как и обычный вызов метода.

...