gpt4 book ai didi

Java8动态代理和默认方法

转载 作者:搜寻专家 更新时间:2023-10-30 19:41:36 26 4
gpt4 key购买 nike

为具有默认方法的接口(interface)提供动态代理,我该如何调用默认方法?通过使用类似 defaultmethod.invoke(this, ...) 的方法,您只需调用代理调用处理程序(这在某种程度上是正确的,因为您没有此接口(interface)的实现类)。

我有一个解决方法,使用 ASM 创建一个实现接口(interface)的类,并将此类调用委托(delegate)给此类的一个实例。但这不是一个好的解决方案,特别是如果默认方法调用其他接口(interface)方法(你得到一个委托(delegate)乒乓)。 JLS 对这个问题出奇地沉默......

这里是一个小代码示例:

public class Java8Proxy implements InvocationHandler {
public interface WithDefaultMethod {
void someMethod();

default void someDefaultMethod() {
System.out.println("default method invoked!");
}
}

@Test
public void invokeTest() {
WithDefaultMethod proxy = (WithDefaultMethod) Proxy.newProxyInstance(
WithDefaultMethod.class.getClassLoader(),
new Class<?>[] { WithDefaultMethod.class }, this);
proxy.someDefaultMethod();

}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

// assuming not knowing the interface before runtime (I wouldn't use a
// proxy, would I?)
// what to do here to get the line printed out?

// This is just a loop
// method.invoke(this, args);

return null;
}
}

最佳答案

您可以使用 MethodHandles输入您的InvocationHandler。此代码复制自 Zero Turnaround .

Constructor<MethodHandles.Lookup> constructor;
Class<?> declaringClass;
Object result;

if (method.isDefault()) {
declaringClass = method.getDeclaringClass();
constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);

constructor.setAccessible(true);

result = constructor.
newInstance(declaringClass, MethodHandles.Lookup.PRIVATE).
unreflectSpecial(method, declaringClass).
bindTo(proxy).
invokeWithArguments(args);

return(result);
}

关于Java8动态代理和默认方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26206614/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com