加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java – Generic ChangeListener

发布时间:2020-12-15 08:30:06 所属栏目:Java 来源:网络整理
导读:场景: 我有一个容器对象,它包含一个混合的对象包,所有对象都继承自MyContainedObject类.容器类的使用者无法直接访问包含的对象,但我有兴趣知道它们何时发生更改. 设计决策: 在特定类类型上侦听ChangeEvents的最佳方法是什么?我最初的想法是用泛型做点什么
场景:

我有一个容器对象,它包含一个混合的对象包,所有对象都继承自MyContainedObject类.容器类的使用者无法直接访问包含的对象,但我有兴趣知道它们何时发生更改.

设计决策:

在特定类类型上侦听ChangeEvents的最佳方法是什么?我最初的想法是用泛型做点什么.例如,

private TreeMap<Class,ChangeListener> listeners;

public <T extends MyContainedObject> addChangeListenerForObjectsOfType(Class<T> className,ChangeListener listener)
{
   listeners.put(className,listener);
}

当检测到更改时,容器类将遍历列表并仅通知为该类类型注册的侦听器.

其他建议?

谢谢.

解决方法

我假设你的TreeMap上的键类型是一个类,而不是MyContainedObject.

如果你真的需要在特定的类类型上监听ChangeEvents,并且你希望即使在设置了监听器之后也能够向你的集合添加元素,这看起来很合理.您可能希望支持相同类型的多个侦听器,因此您应该使用Multimap类(Google Collections有一些)或使用集合(可能是IdentityHashSet)作为Map中的值.

您可能还希望向ChangeListener添加一个类型参数,以便侦听器可以获取已触发的事件已经转换为适当类型的对象.

interface ChangeListener<T> {
    void changed(T obj,/* whatever */);
}

您必须在容器内部进行未经检查的强制转换才能使其正常工作,但只要您的侦听器添加方法做正确的事情,它就应该是安全的.例如:

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)) {
            // safe because signature of addChangeListener guarantees type match
            @SuppressWarnings("unchecked")
            Set<ChangeListener<? super T>> listeners =
                (Set<ChangeListener<? super T>>) entry.getValue();
            result.addAll(listeners);
        }
    }
    return result;
}

一个小问题:我避免使用“className”作为包含Class对象的变量的名称.类名是一个String,通常是Class.getName()等的结果.这有点烦人,但我通常看到的惯例是避免绕过“class”是保留字的事实拼错它可以是“klass”或“cls”.

此外,如果您在添加听众后不需要更新集合的能力,那么我会选择akf建议的内容,因为它更简单.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读