Can';t解决此Java泛型编译时警告 请考虑以下代码: public abstract class Subject { private Collection<Observer> observerCollection = new HashSet<>(); // ... protected void notifyObservers() { this.observerCollection.stream().filter(Objects::nonNull).forEach(o -> o.update(this)); } } public interface Observer<T extends Subject> { void update(T subject); }
在Can';t解决此Java泛型编译时警告 请考虑以下代码: public abstract class Subject { private Collection<Observer> observerCollection = new HashSet<>(); // ... protected void notifyObservers() { this.observerCollection.stream().filter(Objects::nonNull).forEach(o -> o.update(this)); } } public interface Observer<T extends Subject> { void update(T subject); },java,generics,observer-pattern,Java,Generics,Observer Pattern,在观察者中使用泛型的动机是避免投射subject参数,以便观察者可以检索主题的状态。这与流无关;直截了当是行不通的 作为观察者我会关注受试者和观察者之间传递的值。即,两个类都有一个类型参数,相关方法确保类型兼容: public interface Observer<T> { void update(T value); // no subject, but a value } public class Subject<T> { private Coll
观察者
中使用泛型的动机是避免投射subject
参数,以便观察者可以检索主题的状态。这与流无关;直截了当是行不通的
作为
观察者我会关注受试者
和观察者
之间传递的值。即,两个类都有一个类型参数,相关方法确保类型兼容:
public interface Observer<T> {
void update(T value); // no subject, but a value
}
public class Subject<T> {
private Collection<Observer<? super T>> observers = new HashSet<>();
protected void notifyObservers() {
this.observers.stream().filter(Objects::nonNull).forEach(o -> o.update(this.getValue()));
}
public void addObserver(Observer<T> observer) { // adding the right kind of observer
observers.add(observer);
}
abstract public T getValue(); // returning the value - this one is abstract
}
您可以这样将它们组合在一起:
IntegerContainer container = new IntegerContainer(3);
IntegerObserver observer = new IntegerObserver();
container.addObserver(observer);
container.notifyObservers();
@路易斯瓦瑟曼是的,我试过了,结果也一样。我同意,但只是Collection
给了我一个rawtype
和一个unchecked
警告。你使用的是rawtype。不要那样做。另外,不要将您的类型命名为与众所周知的Java API类型相同的类型,尤其是不要从Java.lang..
或Java.util..
包中命名。我想退一步:为什么需要主题泛型类型?您希望强制执行哪种约束?我相信这个Observer.update
将允许几乎每个主体及其各自的观察者:void update(Subject-Subject)
@TamasRev问得好!在实现Observer
的类的update()
方法中,我希望避免将Subject
参数强制转换为特定类型,以便接收状态更新。我会补充这个问题,包括动机。也许我应该把问题变成如何避免警告。现在这个问题更有意义了吗?这会改变你的答案吗?一点也不会。除了完全放弃Subject
并让它的每个子类型自己做观察者的工作之外,没有任何方法可以避免警告。我不知道编辑之前这个问题是什么样子,但目前它仍然显示了observer
的用法(简单的坏名字)作为一个原始类型。@RaffiKhatchadourian,它可以同时计算出这两种类型,但这些前提不足以证明这个是t
这个
可能是主题
的其他子类型,除了T
。
public interface Observer<T> {
void update(T value); // no subject, but a value
}
public class Subject<T> {
private Collection<Observer<? super T>> observers = new HashSet<>();
protected void notifyObservers() {
this.observers.stream().filter(Objects::nonNull).forEach(o -> o.update(this.getValue()));
}
public void addObserver(Observer<T> observer) { // adding the right kind of observer
observers.add(observer);
}
abstract public T getValue(); // returning the value - this one is abstract
}
public class IntegerContainer extends Subject<Integer> {
private int value;
public IntegerContainer(int value) {
this.value = value;
}
@Override
public Integer getValue() {
return value; // this is the parameter of the update() call
// you could even compute here something
// you can pass entire objects too, if required
}
}
public class IntegerObserver implements Observer<Integer> {
private int cachedInteger;
@Override
public void update(Integer value) {
this.cachedInteger = value; // no cast here
} // ...
}
IntegerContainer container = new IntegerContainer(3);
IntegerObserver observer = new IntegerObserver();
container.addObserver(observer);
container.notifyObservers();