Java名称冲突错误,尽管方法签名不同

时间:2014-05-21 14:13:56

标签: java generics java-8 type-erasure name-clash

为了好玩,我试图实现一个" MultiMap"集合,就像Apache Commons库中已经存在的那样。我的#"删除(K键,V值)"我收到了一个有趣的错误。方法。编译器说有一个名称冲突 - 它与"删除(对象,对象)类型为Map"具有相同的擦除功能。但是java.util.Map接口中没有定义这样的方法!只有"删除(对象)"方法 - 使用一个参数,而不是我的两个参数版本。更有趣的是,如果您通过替换我的"删除(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 个答案:

答案 0 :(得分:15)

  

但是java.util.Map接口中没有定义这样的方法!

Map接口中的Map#remove(Object, Object)方法;它是在Java 8中添加的。因此错误。

答案 1 :(得分:1)

当java泛型类型转换为字节码时,这是类型擦除过程。

在运行时,Map中的default boolean remove(Object key, Object value)(此方法是Java 8中的新方法)与MultiMap类public boolean remove(K key, V value)中的方法相同。

编译器看到了这一点,因此显示错误:

名称冲突:MultiMap类型的方法remove(K,V)与AbstractMap类型的remove(Object,Object)具有相同的擦除功能但不支持  覆盖它。

请参阅:http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html

相关问题