Я пытаюсь создать универсальный boradcaster, на который клиентский код может подписаться. Затем клиентский код будет обновлен (через ReportListener), когда любые изменения будут в режиме для конкретных подклассов Reporter_Abstract.
Я знаю, что я перестал использовать дженерики здесь (например,
public abstract class Reporter_Abstract<I extends Reporter_Abstract<I>>
чувствует себя грязным), но я не уверен, как применить эти требования по-другому. Как я могу гарантировать, что слушатель, добавленный в код, обрабатывает изменения I, где I является подтипом Reporter_Abstract
public abstract class Reporter_Abstract<I extends Reporter_Abstract<I>>
{
private final List<ReportListener<I>> _listeners;
/**
* Broadcast change to any attached listeners, skipping the sender
*/
protected final void reportChange( ReportListener<I> sender )
{
List<ReportListener<I>> listeners = collectListeners();
for( ReportListener<I> listener : listeners )
{
try
{
if( sender == null || sender != listener )
{
listener.recognizeChange( (I) this );
}
}
catch( Exception e )
{
_log.error( "Uncaught exception from listener: " + listener, e );
}
}
}
}
public class SomeStateReporter extends Reporter_Abstract<SomeStateReporter>
{
private boolean _isSomeStateActive;
public void setSomeStateActive( boolean isSomeStateActive )
{
if( isSomeStateActive ^ _isSomeStateActive )
{
_isASomeStateActive = isSomeStateActive;
super.reportChange();
}
}
}
public interface ReportListener<T extends Reporter_Abstract<?>>
{
public void recognizeChange( T report );
}
И класс, который хочет слушать изменения
public class ChangeHandlingClass()
{
public void attachSomeStateListener( SomeStateReporter someStateReporter )
{
sometateReporter.addListener( new SomeStateUpdateListener() );
}
private class SomeStateUpdateListener implements ReportListener<SomeStateReporter>
{
@Override
public void recognizeChange( SomeStateReporter report )
{
handleStateChange( report.isSomeStateActive()
}
}
}
Если это правильный путь (или правильный путь), то не должна ли эта строка
listener.recognizeChange( (I) this );
позвольте мне использовать аргумент 'this' без приведения и знать, что это определение I?
Я далеко от базы?