Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Is the unchecked cast actually safe here?</p> </blockquote> <p>Quite. Your code will not cause heap pollution because the signature of subcribe ensures that you only put IEventSubscribers of the proper compile time type into the map. It might propagate heap pollution caused by an unsafe unchecked cast elsewhere, but there is little you can do about that.</p> <blockquote> <p>How can I actually check to see if the items in the subscriber list implement IEventSubscriber?</p> </blockquote> <p>By casting each item to <code>IEventSubscriber</code>. Your code already does this in the following line:</p> <pre><code>for (IEventSubscriber&lt;T&gt; subscriber: existingSubscribers) { </code></pre> <p>If <code>existingSubscribers</code> contained an object not assignable to <code>IEventSubscriber</code>, this line would throw a ClassCastException. Standard practice to avoid a warning when iterating over a list of unknown type parameter is to explicitly cast each item:</p> <pre><code>List&lt;?&gt; list = ... for (Object item : list) { IEventSubscriber&lt;T&gt; subscriber = (IEventSubscriber&lt;T&gt;) item; } </code></pre> <p>That code explicitly checks that each item is an <code>IEventSubscriber</code>, but can not check that it is an <code>IEventSubscriber&lt;T&gt;</code>.</p> <p>To actually check the type parameter of <code>IEventSubscriber</code>, the <code>IEventSubscriber</code> needs to help you out. That is due to erasure, specifically, given the declaration</p> <pre><code>class MyEventSubscriber&lt;T&gt; implements IEventSubscriber&lt;T&gt; { ... } </code></pre> <p>the following expression will always be true:</p> <pre><code>new MyEventSubscriber&lt;String&gt;.getClass() == new MyEventSubscriber&lt;Integer&gt;.getClass() </code></pre> <blockquote> <p>Presuming that (2) involves some nasty reflection, what would you do here?</p> </blockquote> <p>I'd leave the code as it is. It is quite easy to reason that the cast is correct, and I would not find it worth my time to rewrite it to compile without warnings. If you do wish to rewrite it, the following idea may be of use:</p> <pre><code>class SubscriberList&lt;E&gt; extends CopyOnWriteArrayList&lt;E&gt; { final Class&lt;E&gt; eventClass; public void trigger(Object event) { E event = eventClass.cast(event); for (IEventSubscriber&lt;E&gt; subscriber : this) { subscriber.trigger(event); } } } </code></pre> <p>and </p> <pre><code>SubscriberList&lt;?&gt; subscribers = (SubscriberList&lt;?&gt;) subscriptions.get(eventClass); subscribers.trigger(message); </code></pre>
    singulars
    1. This table or related slice is empty.
    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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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