(Для целей этого поста, позволяет выделить java.util.Observable)Java Тип подстановочные знаки
Я экспериментировал вокруг с обобщениями, а затем шаблонными типами. Цель заключалась в создании универсального наблюдаемого кэш-памяти с дельтами, предоставляемыми наблюдателям. Там, где это начинает сходить с рельсов, я хотел разрешить использование более общих наблюдателей, чем тот, который указан в Observable, например. Observer<Object>
или некоторые другие обычные суперклассы.
С тех пор я пришел к выводу, что это слишком сложно для моего варианта использования, но сама проблема продолжает беспокоить меня, так как я явно не понимаю, как правильно использовать подстановочные знаки типа.
Так что, если мы начнем с простым интерфейсом наблюдателя:
public interface Observer<T> {
public void notifyChange(ChangeHolder<T> change);
}
и связанным с ним ChangeHolder, в полной реализации этого будет более сложным, предоставляя списки добавленных/обновленные/удаленных объектов, но это достаточно чтобы продемонстрировать этот вопрос
public interface ChangeHolder<T> {
T getChange();
}
Так с наблюдателем, определенным, я попытался реализовать Observable абстрактного класса:
public abstract class Observable<T> {
private Set<Observer<? super T>> observers = new HashSet<>();
public void addObserver(Observer<? super T> obs){
observers.add(obs);
}
public void change(ChangeHolder<T> changes){
for(Observer<? super T> obs : observers){
obs.notifyChange(changes);
}
}
}
И с этим я мог бы определить некоторые кэши объектов, объявив что-то вроде class TreeCache extends ObservableCache<Tree>
(с этого момента я буду использовать Tree как примерный класс, который будет использоваться как T, предположим, что это простое POJO, распространяющееся только от Объект) и передать ChangeHolder<Tree>
объектам на TreeCache.change()
при необходимости. К сожалению, компилятор не согласен:
The method notifyChange(ChangeHolder<capture#2-of ? super T>) in the type Observer<capture#2-of ? super T> is not applicable for the arguments (ChangeHolder<T>)
Вот где мое понимание заканчивается.
Без класса ChangeHolder (если в моем методе notifyChange вместо этого использовался простой T), он отлично работает, так как вполне законно передавать Tree в Observer.notifyChange (Object).
Я сделал вывод, что я должен быть в состоянии сделать то же самое с ChangeHolder - ChangeHolder<T>
должны удовлетворять notifyChange(ChangeHolder<? super T>)
таким же образом, что T
удовлетворяет notifyChange(? super T)
но четко я-то недоразумение?
Спасибо за быстрый ответ. Глядя на ваше предложение №2 сначала, если я не ошибаюсь, избавляясь от подстановочных знаков, означает, что тип моих экземпляров Observer должен точно соответствовать типам, поэтому я не смог бы привязать 'Observer
@StrangelyTyped Это правда. Это должно быть 1. в этом случае. Вы также можете изменить 'change' на' public void change (ChangeHolder extends T> changes) '. –
Извините, новичок в SO, случайно отправил комментарий раньше, используя ваше предложение # 1 Я не могу прикрепить 'Observer