为了好玩,我正在尝试实现一个"MultiMap"集合,就像Apache Commons库中已经存在的那样。我得到了一个有趣的错误与我的"删除(K键,V值)"方法。编译器说存在名称冲突——它与"remove(Object, Object) of type Map"具有相同的擦除功能。但是在java.util.Map接口中没有定义这样的方法!只有一个"remove(Object)"方法-只有一个参数,而不是我的两个参数版本。更有趣的是,如果您手动删除类型信息,将我的"remove(K键,V值)"替换为"remove(Object键,Object值)",它会编译得很好。有人能解释一下这个现象吗?
我正在运行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();
}
}
但是在java.util.Map接口中没有定义这样的方法!
在Map
接口中存在一个Map#remove(Object, Object)
方法;它是在Java 8中添加的。
这是由于java泛型类型转换为字节码时类型擦除过程造成的。
在运行时default boolean remove(Object key, Object value)
(这个方法在Java 8中是新的)在Map是相同的方法在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