Note that there are some explanatory texts on larger screens.

plurals
  1. POAvoiding an unchecked cast for cast to a collection of a generic interface in Java for an event publisher
    primarykey
    data
    text
    <p>I'm trying to create a lightweight, thread-safe in-app publish/subscribe mechanism for an Android app that I'm building. My basic approach is to keep track of a list of <code>IEventSubscriber&lt;T&gt;</code> for each event type T and then be able to publish events to subscribing objects by passing along a payload of type T.</p> <p>I use generic method parameters to (I think) ensure that subscriptions are created in a type safe way. Thus, I'm pretty sure that when I obtain the list of subscribers from my subscription map when it comes time to publish an event that I'm OK casting it to a list of <code>IEventSubscriber&lt;T&gt;</code>, however, this generates the unchecked cast warning.</p> <p>My questions:</p> <ol> <li>Is the unchecked cast actually safe here?</li> <li>How can I actually check to see if the items in the subscriber list implement <code>IEventSubscriber&lt;T&gt;</code>?</li> <li>Presuming that (2) involves some nasty reflection, what would you do here?</li> </ol> <p>Code (Java 1.6):</p> <pre><code>import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArraySet; public class EventManager { private ConcurrentMap&lt;Class, CopyOnWriteArraySet&lt;IEventSubscriber&gt;&gt; subscriptions = new ConcurrentHashMap&lt;Class, CopyOnWriteArraySet&lt;IEventSubscriber&gt;&gt;(); public &lt;T&gt; boolean subscribe(IEventSubscriber&lt;T&gt; subscriber, Class&lt;T&gt; eventClass) { CopyOnWriteArraySet&lt;IEventSubscriber&gt; existingSubscribers = subscriptions. putIfAbsent(eventClass, new CopyOnWriteArraySet&lt;IEventSubscriber&gt;()); return existingSubscribers.add(subscriber); } public &lt;T&gt; boolean removeSubscription(IEventSubscriber&lt;T&gt; subscriber, Class&lt;T&gt; eventClass) { CopyOnWriteArraySet&lt;IEventSubscriber&gt; existingSubscribers = subscriptions.get(eventClass); return existingSubscribers == null || !existingSubscribers.remove(subscriber); } public &lt;T&gt; void publish(T message, Class&lt;T&gt; eventClass) { @SuppressWarnings("unchecked") CopyOnWriteArraySet&lt;IEventSubscriber&lt;T&gt;&gt; existingSubscribers = (CopyOnWriteArraySet&lt;IEventSubscriber&lt;T&gt;&gt;) subscriptions.get(eventClass); if (existingSubscribers != null) { for (IEventSubscriber&lt;T&gt; subscriber: existingSubscribers) { subscriber.trigger(message); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload