2015-10-27 2 views
1

Я проектирование класса контейнера, который предназначен для хранения пары реализацийGeneric производителя и потребитель

public interface MetaData<ValueType>{ 
    public String getName(); 
} 

и соответствующего значения параметра ValueType типа. Так что я написал это (принудительную реализацию некоторых инвариантов опущен):

public final class ParametersImpl implements Parameters{ 

    private final Map<MetaData<?>, Object> parameters; 
    { 
     parameters = new HashMap<>(); 
    } 

    @Override 
    public Object getValue(MetaData<?> pmd) { 
     return parameters.get(pmd); 
    } 

    @Override 
    public <M> void put(MetaData<M> p, M value) { 
     parameters.put(p, value); 
    } 
} 

где

public interface Parameters { 

    public Object getValue(MetaData<?> pmd); 
    public <M> void put(MetaData<M> p, M value); 
} 

Дело в том, когда клиент вызывает метод Object getValue(MetaData<?> pmd) они должны делать явное приведение:

MetaData<List<Integer>> metaData; 
Paramters params; 
List<Integer> list= new ArrayList<>(); 
//intialization 
params.put(metaData, list); 
//do some other 
List<Integer> lst = (List<Integer>) params.getValue(metaData); 

Хотя бросок полностью безопасен, я хотел бы избежать его и предоставить какой-то общий метод. Но когда я пытаюсь это заявление:

public <M> M getValue(MetaData<M> pmd); 

я получил компиляции ошибки в реализации:

public <M> M getValue(MetaData<M> pmd) { 
    return parameters.get(pmd); //cannot convert capture-of-#1 to M 
} 

ВОПРОС: Есть ли способ generify метод public Object getValue(MetaData<?> pmd); каким-либо образом?

+0

Ваш HashMap объявляется иметь значение типа 'Object'. Предположительно, это должен быть какой-то общий тип ...? – khelwood

+0

Не могли бы вы сделать бросок внутри 'getValue'? –

+2

Просто нажмите: 'return (M) parameters.get (pmd)' и аннотируйте метод с помощью '@SuppressWarnings (« unchecked »)' – Raffaele

ответ

2

Вам просто нужно привести значение, извлеченное из карты:

public <M> M getValue(MetaData<M> pmd) { 
    return (M) parameters.get(pmd); 
} 

Но в этот момент компилятор жалуется, что не может проверить бросок. Что это значит? Ну, нормальный листинг в Java исходный код выражается (SomeType) val - компилятор проверяет, что операция не является полностью незаконной (например, вы не можете наложить String ссылку на) и испускает байт-код, который выполняется во время выполнения , когда он может выбросить ClassCastException.

При создании ссылки с переменной типа компилятор не может испускать такой байт-код, потому что переменная типа не существует во время выполнения, поэтому вместо этого выдается предупреждение о компиляции. Вы должны:

  • убедитесь, что карта заполняется с правильными значениями
  • подавляющих предупреждение с @SuppressWarnings("unchecked")
Смежные вопросы