gpt4 book ai didi

java - 在委托(delegate)另一个包中的接口(interface)的方法时,如何使委托(delegate)类成为非公开的?

转载 作者:行者123 更新时间:2023-11-30 07:06:38 30 4
gpt4 key购买 nike

在我的库中,我正在生成客户端提供的接口(interface)的实现(用库中的自定义指令进行注释)。我使用 MethodDelegation 来拦截接口(interface)方法并将它们转发到库包中定义的委托(delegate)类的实例:

package library.pkg;

class ImplBase { }

public class ImplDelegate {

final ImplContext context;

ImplDelegate(ImplContext ctx) {
this.context = ctx;
}

public void impl(
@CustomName String name,
@CustomTags String[] tags,
@AllArguments Object[] args) {

// do things here
}
}

static <T> T implClient(Class<T> clientType) {

MethodDelegation delegation = MethodDelegation
.to(new ImplDelegate(new ImplContext(clientType)))
.filter(not(isDeclaredBy(Object.class)))
.appendParameterBinder(ParameterBinders.CustomTags.binder)
.appendParameterBinder(ParameterBinders.CustomName.binder);

Class<? extends ImplBase> implClass =
new ByteBuddy()
.subclass(ImplBase.class)
.name(String.format("%s$Impl$%d", clientType.getName(), id++))
.implement(clientType)
.method(isDeclaredBy(clientType).and(isVirtual()).and(returns(VOID)))
.intercept(delegation)
.make()
.load(clientType.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();

return clientType.cast(implClass.newInstance());
}

// In client code, get an instance of the interface and use it.
package client.pkg;

interface Client {
void operationA(String p1, long p2);
void operationB(String... p1);
}

Client client = implClient(Client.class);
client.operationA("A", 1);

这可行,但它将 ImplDelegate 公开为库中的公共(public)类型;我宁愿让它保持包私有(private)。实现此目的的一种方法是在运行时在库包中生成 ImplDelegate 的公共(public)子类,该子类使用公共(public)桥接方法代理所有包私有(private)方法,并将其用作委托(delegate)。我研究过 TypeProxy,但我对 ByteBuddy 还不够熟悉,还不知道辅助类型机制是否适合于此。

有没有办法生成运行时代理来实现桥接方法,以便我可以隐藏委托(delegate)实现?

最佳答案

委托(delegate)类型需要对调用它的类可见。你只有两种可能性:

  1. 在与拦截器相同的包中创建一个类型。确保将生成的类注入(inject)拦截器的类加载器中,包私有(private)类型仅对同一类加载器中同一包的类可见。但是,这样您就只能实现公共(public)接口(interface)。
  2. 在运行时,子类化您的拦截器并确保所有拦截器方法都是公共(public)的。 Byte Buddy默认生成一个公共(public)子类:

    Object delegate = new ByteBuddy()
    .subclass(ImplDelegate.class)
    .make()
    .load(ImplDelegate.class.getClassLoader())
    .getLoaded()
    .newInstance();

    上述类型将是公共(public)的,这样您现在就可以委托(delegate)给此实例,即使 ImplDelegate 是包私有(private)的。但请注意,这仅影响编译时可见性,在运行时,ImplDelegate 的子类对任何类型都可见。 (但是,构造函数仍然是包私有(private)的,即使对于子类也是如此。)

关于java - 在委托(delegate)另一个包中的接口(interface)的方法时,如何使委托(delegate)类成为非公开的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40008819/

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