I am getting the warning:
[unchecked] Possible heap pollution from parameterized vararg type Class
But I am unsure if it will actually pollute:
public void register(EventListener listener, Class<? extends Event>... eventTypes) {}
Here is the complete implementation if that is necessary:
public class EventDispatcher {
public static ConcurrentLinkedQueue<Event> eventQueue;
public static ConcurrentHashMap<Class<? extends Event>, CopyOnWriteArrayList<EventListener>> eventsListenerMap =
new ConcurrentHashMap<>();
public static void register(EventListener listener, Class<? extends Event>... eventTypes) {
for (Class<? extends Event> eventType : eventTypes) {
if (eventsListenerMap.containsKey(eventType)) {
eventsListenerMap.get(eventType).addIfAbsent(listener);
} else {
CopyOnWriteArrayList<EventListener> initializingListeners =
new CopyOnWriteArrayList<>();
initializingListeners.add(listener);
eventsListenerMap.put(eventType, initializingListeners);
}
}
}
}
I am all up for OT-suggestions for improving this, too, but keep in mind that this class is unfinished.
The warning about generic varargs is related to the dangers of generic arrays. Theoretically the method could abuse array covariance with the passed in array to cause heap pollution, for example:
Class<?>[] eventTypesWithWidenedType = eventTypes;
eventTypesWithWidenedType[0] = String.class;
Class<? extends Event> eventType = eventTypes[0]; // liar!
But it's fine as long as the method implementation doesn't do anything silly like that. Some basic precautions would be:
eventTypes
.eventTypes
outside the method.With Java 7, you could annotate the method with @SafeVarargs, which basically promises the compiler that generic arrays are okay (meaning it's no longer on the caller to suppress the warning).
Whenever you have varargs that are genericized (for example, a genericized list) you have a possibility of heap pollution. For example:
public void doSomethingWithStrings(List<String>... strings) {
Object[] objectArray = strings; //Valid because Object is a valid supertype
objectArray[0] = Arrays.asList(new Integer(42)); //Heap pollution
String string = strings[0].get(0); //Oops! ClassCastException!
}
In your example, you have Class<? extends Event> eventTypes...
which falls prey to the same problem:
public static void register(EventListener listener, Class<? extends Event>... eventTypes) {
Object[] objectArray = eventTypes;
objectArray[0] = String.class; //Heap pollution
...
...
}
Java is just warning you that there is a potential heap-pollution solution. In Java 7, the warnings are generated at the declaration of the method as well whereas in previous versions it was only at the call-sites.
If you are certain that heap-pollution cannot occur, you can suppress the warning using the @SafeVarargs
annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With