我有一组 15-20 个类,它们依赖于一个实现具有绑定类型参数的泛型接口的类。界面如下所示:
interface Handler<F extends Foo, T extends Foo> {
T handleFoo(String methodName, F myFoo);
}
以及 Handler 的单一实现,它使用反射来处理 Foo 的所有专业案例,因为它们都是"相似但不同的"。
class ConcreteHandler<Foo, Foo> implements Handler<Foo, Foo> {
T handleFoo(String methodName, F foo) {
// do your thing
}
}
我希望能够在其协作者中以类型安全的方式使用此类,例如:
@Inject ACollaborator(Handler<Bar, Baz> barHandler) {...}
其中Bar
和Baz
都延伸Foo
.不幸的是,Guice 抱怨当我在我的模块中尝试此操作时Handler<Bar, Baz>
不受约束:
bind(new TypeLiteral<Handler<? extends Foo, ? extends Foo>>() {}).to(ConcreteHandler.class);
我还尝试了以下方法,这会导致编译器错误,因为ConcreteHandler
不是Handler<Bar, Baz>
的子类:
bind(new TypeLiteral<Handler<Bar, Baz>>() {}).to(ConcreteHandler.class);
我有很多这样的 Collaborator 对象,所以我不热衷于为每个类型组合实现 Handler,并为它们放置 20 个单独的绑定语句。
我如何完成我正在使用 Guice 尝试的事情,即将单个具体实现绑定到具有不同泛型参数的单个接口?
可以通过创建表示绑定目标的 TypeLiteral(可能涉及原始类型)来设法执行此操作。
您将在此问题中看到如何执行此操作的示例: 在运行时通过类型和类型文字使用 Guice 重建泛型类型
基本上,您需要的是构造每个处理程序的密钥<>您想要绑定
。然后你可以这样说:
bindHandler(Bar.class, Baz.class);
这将:
- 创建
TypeLiteral<ConcreteFoo<Bar, Baz>>
- 创建
TypeLiteral<Foo<Bar, Baz>>
- 将后者绑定到前者
另外,我认为在您的示例中,ConcreteHandler应该实现Handler[?