2016-06-13 4 views
2

Имея этот интерфейс:Как реализовать ServiceLocator с дженериками?

public interface ServiceLocator { 
    <T> void setService(Class<T> klass, Factory<T> factory) 

    <T> void setConstant(Class<T> klass, T value) 

    <T> T getObject(Class<T> klass) 

} 

Как осуществить? Я имею в виду, как я объявляю данные структуры? Правильно ли это?

private Map<Class, Factory> services = new HashMap<>(); 
private Map<Class, Object> constants = new HashMap<>(); 
+1

Таким образом, вы все равно можете добавить подстановочные знаки, чтобы избавиться от необработанных предупреждений. '' 'Map , Factory >' ''. –

+0

Но не нужно ли использовать дженерики для защиты типов? Я имею в виду мою константу 'константы', которая имеет тип объекта. Имея это, когда я делаю 'getObject' константы, тогда я вынужден сделать приведение:' (T) constants.get (klass); 'И это неправильно, не так ли? – anat0lius

+0

Вы не можете получить этот уровень безопасности через систему типов. Но у вас уже есть (большинство) это в форме инкапсуляции. –

ответ

0

Решение:

private Map<Class<?>, Factory<?>> services = new HashMap<>(); 
private Map<Class<?>, Object> constants = new HashMap<>(); 

Добавить директиву -Xlint:unchecked в параметры компилятора. И @SuppressWarnings("unchecked") о методах, в которых вы нуждаетесь. В моем случае есть метод getObject.

0
private Map<Class, Factory> services = new HashMap<>(); 
private Map<Class, Object> constants = new HashMap<>(); 

Если вы хотите использовать эти структуры можно объявить так:

private Map<Class<?>, Factory<T>> services = new HashMap<>(); 
private Map<Class<?>, Object> constants = new HashMap<>(); 

Не забудьте поместить Factory<T> поймать тип. Использование класса предоставляет вам использовать AnyClass.class как ключевой

Btw вы можете поместить все в одной карте, как private Map<Class<?>, Object> и в функции извергаются, если это завод или нет;)

+0

'Карта , Factory > услуг, которых не может быть, потому что я не хотите, чтобы реализация была общей, а только методы. И положить все в одну карту - это вариант, но я предпочитаю иначе, это то же самое, но более чистое, не так ли? – LiLou1

+0

Ну да, это чище с двумя картами, если это тот случай;) – Raskayu

0

У Guava есть интерфейс, предназначенный для аналогичной цели: ClassToInstanceMap<B>. API является:

<T extends B> T getInstance(Class<T> type); 
<T extends B> T putInstance(Class<T> type, T value); 

Глядя на реализацию в MutableClassToInstanceMap.java, мы видим, что он использует HashMap<Class<? extends B>, B> завернутые в ConstrainedMap. Его MapConstraint использует java.lang.Class.cast(), чтобы гарантировать, что все значения на карте являются юридическими экземплярами соответствующих ключей.

С B часто бывает Object, реализация HashMap заканчивается только тем, что является HashMap<Class<? extends Object>, Object>.

Смежные вопросы