Зачем использовать рефлексию для доступа к членам класса, когда MethodHandle быстрее?
С выпуском Java 7 появился MethodHandle
, который позволяет пользователю вызывать метод, как если бы он использовал свой базовый байт-код. В частности, класс MethodHandles.Lookup
предоставляет методы factory для создания меток для доступа к членам класса:
Методы factory объекта Lookup соответствуют всем основным вариантам использования для методов, конструкторов и полей. Каждый дескриптор метода, созданный с помощью метода factory, является функциональным эквивалентом поведения конкретного байт-кода.
Функционально это более или менее эквивалентно использованию отражения для доступа к этим же членам класса, но обработчики методов быстрее, чем отражение.
Итак, есть ли причина по-прежнему использовать функции отражения, такие как Field#get(..)
/Method.invoke(..)
или эти методы эффективно устарели с введением более быстрых методов?
Обратите внимание, что, хотя дескрипторы методов были введены в Java 7, мой вопрос в первую очередь относится к Java 8, в котором они были оптимизированы, чтобы предположительно достичь производительности, приблизительно равной прямым вызовам полей/методов, превосходя способность отражения.
Ответы
Ответ 1
Рефлексия и методы обрабатывают разные цели и существуют на разных уровнях абстракции. Вы должны использовать тот, который подходит для проблемы, которую вы решаете.
Отражение - это механизм самоанализа общего назначения, который включает в себя множество функций, которые отсутствуют в механизме дескриптора метода, например перечисление членов класса (Class.getMethods()
), проверка характеристик элемента, такого как его флаги доступности, проверка общие подписи членов и т.д.
Кроме того, отражающие объекты могут свободно делиться без предоставления доступа к шари, поскольку проверки доступа выполняются при каждом вызове; обработчики метода придают шари возможность вызова. Таким образом, они также имеют различные последствия для безопасности.
Обработчики методов - это низкоуровневый механизм поиска, адаптации и вызова методов. Хотя вызов с помощью обработчиков методов происходит быстрее, чем через отражение (хотя на сегодняшний день прямой вызов байт-кода по-прежнему, как правило, быстрее, чем вызов обработчика метода), обработчики методов также значительно сложнее использовать, поскольку они автоматически не выполняют адаптацию, которую ожидали бы пользователи Java ( например преобразование аргумента String в Object), что приводит к ошибкам связи.
Библиотека отражения предназначена для основных пользователей Java; уровень дескриптора метода больше нацелен на разработчиков сценариев компилятора и языка. Выберите инструмент, предназначенный для работы.
Ответ 2
tl; dr Нет. Вы должны использовать (и предпочитаете) MethodHandles
в API Core Reflection, когда сможете.
MethodHandles.Lookup
доступ говорит (частично),
В отличие от API Core Reflection, где каждый раз, когда вызывается рефлексивный метод, проверяется доступ, проверяется проверка доступа к методу обработки при создании дескриптора метода.