Ошибка конфликта имен Java, несмотря на разные сигнатуры методов

Ради интереса я пытаюсь реализовать коллекцию "MultiMap", как то, что уже существует в библиотеке Apache Commons. Я получаю интересную ошибку с моим методом "удалить (ключ K, значение V)". Компилятор говорит, что есть конфликт имен - он имеет такое же стирание, что и "удалить (объект, объект) типа Map". Но в интерфейсе java.util.Map такой метод не определен! Только метод "удалить (Object)" - с одним параметром, в отличие от моей версии с двумя параметрами. Еще более интересно то, что если вы вручную удалите информацию о типе, заменив мой "удалить (ключ K, значение V)" на "удалить (ключ объекта, значение объекта)", он скомпилируется нормально. Кто-нибудь может объяснить это явление?

Я использую Java 8, если это важно.

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MultiMap<K, V> extends AbstractMap<K, Collection<V>>
{
    private Map<K, Collection<V>> map;

    public MultiMap()
    {
        super();
        map = new HashMap<>();
    }

    //Fine
    public void clear(K key)
    {
        get(key).clear();
    }

    //Fine
    public boolean add(K key, V value)
    {
        if(!containsKey(key))
            put(key, new ArrayList<>());
        return get(key).add(value);
    }

    //KABOOM!!
    //"Name clash: The method remove(K, V) of type MultiMap<K,V> has the same erasure as remove(Object, Object) of type Map<K,V> but does not override it"
    public boolean remove(K key, V value)
    {
        if(!containsKey(key))
            return false;
        return get(key).remove(value);
    }

    @Override public Collection<V> put(K key, Collection<V> values)
    {
        return map.put(key, values);
    }

    @Override public Set<java.util.Map.Entry<K, Collection<V>>> entrySet()
    {
        return map.entrySet();
    }
}

2 ответа

Решение

Но в интерфейсе java.util.Map такой метод не определен!

Есть Map#remove(Object, Object) метод в Map интерфейс; он был добавлен в Java 8. Отсюда и ошибка.

Это связано с процессом стирания типа, когда универсальный тип Java преобразуется в байт-код.

Во время выполнения default boolean remove(Object key, Object value) (этот метод является новым в Java 8) в Map такой же, как ваш метод в классе MultiMap public boolean remove(K key, V value),

Компилятор видит это и, следовательно, показывает ошибку:

Конфликт имен: метод remove(K,V) типа MultiMap имеет такое же стирание, что и метод remove(Object, Object) типа AbstractMap, но не переопределяет его.

Смотрите это: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html

Другие вопросы по тегам