2014-10-30 2 views
1

Как сравнить два экземпляра MethodHandle? Я ожидаю, что функция вернет true, если дескрипторы указывают на тот же метод. Это не похоже на переопределение класса equals() или hashcode(). Безопасно ли использовать оператор равенства (==)?Как сравнить экземпляры MethodHandle?

ответ

2

Прежде всего, MethodHandle s может не только инкапсулировать целевой метод, но и поведение . Например. у вас могут быть два метода, указывающие на один и тот же метод, но один инкапсулирующий не виртуальный (super. …) вызов, а другой - обычный виртуальный вызов. Эти ручки не могут быть равны.

Кроме того, нет никакого определенного равенства для MethodHandle s в любом случае. Они там, чтобы позволить призывание но не самоанализ:

JVMSpec §5.4.3.5. Method Type and Method Handle Resolution:

Реализация виртуальной машины Java не требуется стажер типов метод или метод обрабатывает. То есть две различные символические ссылки на типы методов или дескрипторы методов, которые являются структурно идентичными, могут не разрешаться для одного и того же экземпляра java.lang.invoke.MethodType или java.lang.invoke.MethodHandle соответственно.


Однако, начиная с Java 8 есть функция, которая позволяет вникать прямойMethodHandle, Lookup.revealDirect. Для дескрипторов, для которых эта операция завершается успешно, вы можете использовать информацию в возвращаемом MethodHandleInfo, чтобы узнать, указывают ли две ручки одному и тому же методу.

+0

Из любопытства вы можете привести пример непрямого 'MethodHandle' и как он построен? – Gili

+2

Большинство дескрипторов, возвращаемых фабричными методами в ['MethodHandles'] (http://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandles.html), являются непрямым методом ручки. Проще говоря, дескрипторы, которые непосредственно не нацелены на метод, конструктор или поле, а скорее изменяют поведение другого дескриптора, являются непрямыми ручками. Но также [постоянная обертка] (http://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandles.html#constant-java.lang.Class-java.lang.Object-), который не модифицирует другой дескриптор (но не имеет конкретного целевого метода), не является прямым. – Holger

Смежные вопросы