请求时,如何指定接口及其类型参数?引用OSGi DS中的服务?

时间:2011-03-10 00:44:45

标签: java generics osgi

我有一个界面:

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;分别。

2 个答案:

答案 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。