Java name clash error, despite different method signatures

我怕爱的太早我们不能终老 提交于 2019-12-10 03:11:28

问题


For fun, I'm trying to implement a "MultiMap" collection, like what already exists in the Apache Commons library. I'm getting an interesting error with my "remove(K key, V value)" method. The compiler says that there is a name clash - that it has the same erasure as "remove(Object, Object) of type Map". But there is no such method defined in the java.util.Map interface! Only a "remove(Object)" method - with one parameter, as opposed to my two parameter version. What's even more interesting is that if you manually remove the type information by replacing my "remove(K key, V value)" with "remove(Object key, Object value)", it compiles fine. Can anyone explain this phenomenon?

I'm running Java 8, in case that matters.

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();
    }
}

回答1:


But there is no such method defined in the java.util.Map interface!

There is a Map#remove(Object, Object) method in the Map interface; it was added in Java 8. Hence the error.




回答2:


This is due type erasure process when a java generic type is translated to bytecode.

At runtime the default boolean remove(Object key, Object value) (this method is new in Java 8) in Map is the same than your method at MultiMap class public boolean remove(K key, V value).

The compiler sees this, and hence shows the error :

Name clash: The method remove(K,V) of type MultiMap has the same erasure as remove(Object, Object) of type AbstractMap but does not override it.

See this: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html



来源:https://stackoverflow.com/questions/23785807/java-name-clash-error-despite-different-method-signatures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!