【发布时间】:2018-01-29 04:57:04
【问题描述】:
我正在尝试构建T extends BaseClient 类型的对象实例工厂,返回的实例具有T 的方法之一重载以执行一些额外的逻辑。我不能修改 T 类的代码(这就是我需要重载的原因),也不能修改基本抽象类 BaseClient 的代码。
使用具体的、定义明确的类型很容易做到这一点。例如,给定一个FooClient extends BaseClient,我可以这样做:
public class FooClientFactory {
public static FooClient create() {
return new FooClient() {
@Override
public void theMethod() {
super.theMethod();
someAdditionalLogic();
}
};
}
}
但在我需要处理可能有许多不同类型的客户(BaseClient 的所有子类)的世界中,我希望拥有这样的东西:
public class ClientFactory<T extends BaseClient> {
public static T create() {
return ...;
}
}
所以我不必为每个具体的子类复制上面的代码。
很遗憾,不能写new T() { ... }。也不能使用Class<T> 并在其上调用newInstance(),因为这不允许我覆盖theMethod() 的行为。使用Proxy 实例将允许我拦截方法调用并匹配方法名称(丑陋)以在需要时执行someAdditionalLogic(),但因为BaseClient 不是一个接口——我不能让它成为一个接口-- 我无法构建代理(更准确地说,在我的实际用例中,我确实有一个可以使用的接口,特定于每个客户端,但是有些地方需要将返回的实例转换为 @987654337 @,由于代理实例的工作方式,返回的 Proxy 实例没有“技术上”实现/宣传,导致 ClassCastExceptions)。
那么,什么给了?这在 Java 中是完全可能的,还是为每个 FooClientFactory 复制粘贴 XXClient 输入我唯一的选择?
【问题讨论】:
-
是否可以传递
Class对象并调用newInstance(),根据this answer,是一种选择吗? -
正如我在问题的倒数第二段中所说,很遗憾,没有。它确实允许我创建一个实例,但我仍然无法覆盖
theMethod()s 的行为。 -
我猜
MyClient的意思是FooClient -
是的,谢谢,在写我的问题时来回走动。现已修复。
-
如果您正在寻找
new T() { ... override ... }解决方案,这在 Java 中是不可能的,对此没有争议(使用诸如 BCEL 之类的工具库的“过度杀伤”例外)。我知道您在这里的实际意图是最大化代码共享或更一般地最小化代码行。我认为 lambda 可能是您在不改变 BaseClient/Factory 框架的情况下最接近的。