TreeMap의 키 유형이 MyContainedObject가 아닌 Class 인 것으로 가정합니다.
실제로 특정 클래스 유형에서 ChangeEvents를 수신해야하는 경우 청취자를 설정 한 후에도 요소를 컬렉션에 추가 할 수있게하려면이 방법은 상당히 합리적입니다. 아마도 동일한 유형의 리스너를 여러 개 지원해야 할 것이므로 Multimap 클래스 (Google Collections 일부)를 사용하거나지도의 값에 컬렉션 (아마도 IdentityHashSet)을 사용해야합니다.
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;
}
작은 사소한 것 : Class 객체를 보유하는 변수의 이름으로 "className"을 사용하지 마십시오. 클래스 이름은 String입니다. 일반적으로 Class.getName() 등의 결과입니다. 약간 짜증나지만, 일반적으로 피할 수있는 규칙은 "class"가 예약어라는 사실을 잊어 버리는 것입니다 그것은 "klass"또는 "cls"중 하나입니다.
또한 청취자를 추가 한 후 컬렉션을 업데이트 할 필요가없는 경우 akf가 제안한 것과 같이 간단하게 처리 할 수 있습니다.
고맙습니다. 이것은 내가 염두에 두었던 것입니다. 또한 MyContainedObject보다는 Class를 의미한다는 점에서 옳습니다. – javacavaj