Я пишу приложение, в котором мне нужно реализовать функциональные интерфейсы во время выполнения. Я заранее не знаю, какие интерфейсы реализовать, но могу разрешить объект Method
, используя отражение от объекта Class
интерфейса.
В целях упрощения вопроса допустим, что япередача объекта Function
, содержащего реализацию метода.
Прямой материал:
@SuppressWarnings("unchecked")
private <T> T implement(Class<T> interfaceType, Method m, Function<Object[], ?> f) {
return (T) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class<?>[]{interfaceType},
(proxy, method, args) -> {
if (method.equals(m)) {
return f.apply(args);
}
// Calls to toString, hashCode, and equals go here.
throw new UnsupportedOperationException(method.getName());
}
);
}
Так что вызовы toString
, hashCode
и equals
в настоящее время не работают,Я явно не хочу этого.
Из документов java.lang.reflect.Proxy
:
Вызов методов hashCode
, equals
или toString
, объявленных вjava.lang.Object
на экземпляре прокси будет кодироваться и отправляться методу вызова обработчика вызова таким же образом, как вызовы метода интерфейса кодируются и отправляются, как описано выше. Класс объявления объекта Method
, переданного для вызова, будет java.lang.Object
. Другие открытые методы экземпляра прокси, унаследованные от java.lang.Object
, не переопределяются прокси-классом, поэтому вызовы этих методов ведут себя так же, как и для экземпляров java.lang.Object
.
Так что я могу переопределить ихметоды, как я хочу. Это круто, но я бы предпочел этого не делать.
Конечно, я мог бы делать фиктивные реализации, которые делают более или менее одно и то же (кроме hashCode
, что составляет native
), или захватывать какой-то другой фиктивный объект (может быть, сам обработчик вызова) и вызвать метод для этого. Но я чувствую, что должен быть в состоянии просто «прорваться» к методам, унаследованным от java.lang.Object
обычным способом. Или, другими словами, вызвать эквивалент super.hashCode()
и т. Д. Непосредственно на proxy
.
Есть ли хороший / стандартный способ сделать это?