我假设您的TreeMap上的键类型应该是一个类,而不是MyContainedObject。
如果您需要监听特定类类型的ChangeEvents,并且您想在设置侦听器后添加元素到集合中,那么这似乎是相当合理的。您可能希望为同一类型支持多个侦听器,因此应该使用Multimap类(
Google Collections有一些)或使用集合(可能是IdentityHashSet)作为Map中值的容器。
您还可以向ChangeListener添加类型参数,以便侦听器可以获取已转换为适当类型的事件对象。
interface ChangeListener<T> {
void changed(T obj, );
}
你需要在容器内进行一个未经检查的类型转换才能使这个工作,但只要你的监听添加方法做得对,那么它应该是安全的。例如:
public <T extends MyContainedObject> addChangeListener(Class<T> klass,
ChangeListener<? super T> listener) {
...
}
private <T extends MyContainedObject> Set<ChangeListener<? super T>> getChangeListeners(T obj) {
Set<ChangeListener<? super T>> result = new IdentityHashSet<ChangeListener<? super T>>();
for (Map.Entry<Class<? extends MyContainedObject>, Set<ChangeListener<?>>> entry : listeners.entrySet()) {
if (entry.getKey().isInstance(obj)) {
@SuppressWarnings("unchecked")
Set<ChangeListener<? super T>> listeners =
(Set<ChangeListener<? super T>>) entry.getValue();
result.addAll(listeners);
}
}
return result;
}
一个小问题:我建议避免使用“className”作为保存Class对象的变量名称。类名是一个字符串,通常是Class.getName()等的结果。这有点让人烦恼,但我通常看到的惯例是避免绕过“class”是一个保留字的事实,将其拼错为“klass”或“cls”。
此外,如果您在添加侦听器后不需要更新集合,则建议采用akf建议的方法,因为它更简单。