Does this mean heap pollution with the wargars?

I get a warning:

[unchecked] Possible heap pollution from the parameterized type vararg Class

But I'm not sure if this will really pollute:

public void register(EventListener listener, Class<? extends Event>... eventTypes) {} 

Here is the full implementation, if 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 in OT suggestions to improve this too, but keep in mind that this class is not complete.

+7
source share
3 answers

A warning about shared varargs is related to the dangers of shared arrays . Theoretically, the method could abuse the covariance of the array with the passed array to cause heap pollution, for example:

 Class<?>[] eventTypesWithWidenedType = eventTypes; eventTypesWithWidenedType[0] = String.class; Class<? extends Event> eventType = eventTypes[0]; // liar! 

But this is fine, as long as the implementation of the method does nothing stupid. Some basic precautions:

  • Do not bind to eventTypes .
  • Do not return or open eventTypes outside the method.

Using Java 7, one could annotate the method using @SafeVarargs , which basically promises the compiler that common arrays are in order (that is, no longer on the caller to suppress the warning).

+7
source

Whenever you have varargs that are generic (like a generic list), you have the possibility of polluting the heap. 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, do you have Class<? extends Event> eventTypes... 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 just warns you that there is a potential heap protection solution. In Java 7, warnings are generated when a method is declared, and in previous versions this was only on call sites.

If you are sure that heap contamination cannot occur, you can suppress the warning using the @SafeVarargs annotation.

+2
source

You need to make sure that the body of the registration method does not throw a ClassCastException at runtime due to illegal arguments. If you are sure that it has been processed, you can safely ignore or suppress the warning.

0
source

All Articles