2016-11-30 4 views
0

Я пытаюсь заставить этот код работать полчаса, и я не знаю, как я должен это исправить. Все остальное не жалуется, но компилятор продолжает кричать на меня, что configurable.value - это не тот же тип, что и configurable.defaultValue. Я довольно смущен, так как ? должен быть подстановочным знаком, не так ли?Правильное использование общих подстановочных знаков

Я довольно новичок в дженериках, поэтому я немного потерян. Я еще не нашел решения.

Есть ли решение, которое не дает никаких предупреждений или ошибок?

ConfigurationManager.class здесь:

public class ConfigurationManager 
{ 
    private final List<Configurable<?>> config; 

    public ConfigurationManager() 
    { 
     config = new ArrayList<Configurable<?>>(); 
    } 

    public void register(Configurable<?> entry) 
    { 
     this.config.add(entry); 
    } 

    public void resetAll() 
    { 
     for(Configurable<?> configurable : this.config) 
     { 
      //Problem here 
      //Type mismatch: cannot convert from capture#3-of ? to capture#2-of ? 
      configurable.value = configurable.defaultValue; 
     } 
    } 
} 

Configurable.class здесь:

public class Configurable<T> 
{ 
    ResourceAddress address; 
    protected T value; 
    protected final T defaultValue; 

    public Configurable(ResourceAddress address, T defaultValue) 
    { 
     this.address = address; 
     this.defaultValue = defaultValue; 
     this.value = this.defaultValue; 
    } 

    public ResourceAddress getAddress() 
    { 
     return address; 
    } 

    public void setValue(T value) 
    { 
     this.value = value; 
    } 

    public T getValue() 
    { 
     return value; 
    } 
} 
+3

Вероятно, существует проблема со строгой интерпретацией типов LHS и RHS. Было бы яснее избежать проблемы полностью с помощью 'protected void resetToDefault()'. – chrylis

ответ

1

Проблема заключается в том, что компилятор не распознает, что value и defaultValue принадлежат одному и тому же объекту, поэтому он не знает, что у них одинаковый тип. Одно из решений заключается в создании типа захвата вспомогательный метод для вызова из вашего цикла:

<T> void resetValue(Configurable<T> configurable) { 
    configurable.value = configurable.defaultValue; 
} 

Как @chrylis указывает, лучшее решение, вероятно, будет добавить метод экземпляра к Configurable:

public void resetValue() { 
    this.value = this.defaultValue; 
} 
+5

Или еще лучше, чтобы поставить это на 'Configurable', в первую очередь, где он принадлежит. – chrylis

+0

Хорошо работает сейчас, спасибо всем. – 493msi