这是否会导致varargs堆污染?

zsa*_*yer 9 java arrays generics variadic-functions

我收到警告:

[unchecked]来自参数化vararg类型Class的可能堆污染

但我不确定它是否真的会污染:

public void register(EventListener listener, Class<? extends Event>... eventTypes) {}
Run Code Online (Sandbox Code Playgroud)

如果有必要,这是完整的实现:

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我一直都在为OT提出改进建议,但请记住,这个课程尚未完成.

Pau*_*ora 8

有关通用变量的警告与泛型数组危险性有关.从理论上讲,该方法可能会滥用数组协方差与传入的数组导致堆污染,例如:

Class<?>[] eventTypesWithWidenedType = eventTypes;
eventTypesWithWidenedType[0] = String.class;
Class<? extends Event> eventType = eventTypes[0]; // liar!
Run Code Online (Sandbox Code Playgroud)

但只要方法实现不做那样愚蠢的事情就没关系.一些基本的预防措施是:

  • 不做任何转让eventTypes.
  • 不要返回或以其他方式暴露eventTypes在方法之外.

使用Java 7,您可以使用@SafeVarargs来注释该方法,这基本上承诺编译器通用数组是可以的(这意味着调用者不再禁止警告).