我有一个界面:
interface Foo<T> {
void doSomethingWith(T t);
}
有些实现如:
class Bar implements Foo<String> {
void doSomethingWith(String s) {
// ...
}
}
class Baz implements Foo<Double> {
void doSomethingWith(Double d) {
// ...
}
}
我有一个OSGi服务需要一个Foo&lt; String&gt;的实例(以及需要Foo&lt; Double&gt;等的其他服务。)
有没有办法揭露&amp;从而使用Declarative Services注入实现?我只能弄清楚如何揭露Bar&amp; Baz as Foo&amp;不如Foo&lt; String&gt;和Foo&lt; Double&gt;分别。
答案 0 :(得分:4)
简而言之,由于类型Type Erasure,在运行时没有Foo<String>
这样的东西。类型信息丢失。
相反,您可以将Bar
公开为具有服务属性Foo
的原始typeArg=java.lang.String
,并在将其注入使用者时使用过滤器。
其他方法是引入接口FooString extends Foo<String> { }
,FooDouble extends Foo<Double> { }
并使用它们而不是Foo
。
答案 1 :(得分:0)
在Foo类型中,T被删除为对象。所以界面上的方法是
void doSomethingWith(Object t)
当您将Bar定义为实现Foo&lt; String&gt;时,您最终会得到两种方法,包括编译器生成的合成桥接方法,它采用Object类型。
void doSomethingWith(Object t) {
doSomethingWith((String)t);
}
但就OSGi服务而言,以Foo名称注册的服务类型只是Foo,任何实现它的类都必须具有doSomethingWith(Object t)方法。框架或声明服务没有办法(除了你定义和使用一些服务属性之外)了解服务实现(例如Bar)已经将T定义为String。