Как указать интерфейс и параметры его типа при запросе и обращении к службе в OSGi DS? - PullRequest
0 голосов
/ 10 марта 2011

У меня есть такой интерфейс:

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 (и другойсервис, которому нужен Foo и т. д.).

Есть ли способ раскрыть и, таким образом, внедрить реализации, используя декларативные сервисы?Я могу только понять, как выставить Bar & Baz как Foo, а не как Foo и Foo , соответственно.

Ответы [ 2 ]

4 голосов
/ 10 марта 2011

Короче говоря, нет такой вещи как Foo<String> во время выполнения из-за типа Тип Erasure .Информация о типе теряется.

Вместо этого вы можете выставить Bar как необработанное Foo со свойством службы typeArg=java.lang.String и использовать фильтр при внедрении его потребителю.

Другой способ -ввести интерфейсы FooString extends Foo<String> { }, FooDouble extends Foo<Double> { } и использовать их вместо Foo.

0 голосов
/ 10 марта 2011

В типе Foo T стирается для объекта. Таким образом, метод интерфейса

void doSomethingWith(Object t)

Когда вы определяете Bar как реализующий Foo , вы получаете два метода, включая метод синтетического моста, сгенерированный компилятором, который принимает тип Object.

void doSomethingWith(Object t) {
    doSomethingWith((String)t);
}

Но что касается сервисов OSGi, тип сервиса, зарегистрированный под именем Foo, это просто Foo, и любой класс, который его реализует, должен иметь метод doSomethingWith (Object t). Для платформы или Декларативной службы нет способа (кроме определения и использования некоторых свойств службы) понять, что реализация службы (например, Bar) определила T как String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...