2014-05-21 10 views
8

재미 있기 때문에 Apache Commons 라이브러리에 이미있는 것과 같은 "MultiMap"컬렉션을 구현하려고합니다. 내 "제거 (K 키, V 값)"메서드로 재미있는 오류가 나타납니다. 컴파일러에는 이름 충돌이 있습니다 - "remove (Object, Object) of Map"과 같은 삭제 기능이 있다고합니다. 그러나 java.util.Map 인터페이스에 정의 된 메서드는 없습니다! "remove (Object)"메소드 만 - 두 개의 매개 변수 버전이 아닌 하나의 매개 변수가 있습니다. 더욱 흥미로운 점은 "remove (K key, V value)"를 "remove (Object key, Object value)"로 대체하여 유형 정보를 수동으로 제거하면 잘 컴파일된다는 것입니다. 누구든지이 현상을 설명 할 수 있습니까?다른 메서드 서명에도 불구하고 Java 이름 충돌 오류

중요한 점을 대비하여 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(); 
    } 
} 
+0

흠 내가 거기에 오류를받지 못했습니다. 나는 * put * (key, new ArrayList <>())'호출에 에러가 발생한다. (편집 : Java 7을 사용해 보았습니다.) – arshajii

+0

흥미 롭습니다. 아마도 버전이 중요할까요? 나는 Java 8을 실행하고있다. – TheBrownMotie

+0

@ TheBrownMotie 나는 그것이 중요하다고 생각한다. 나는 SO에서 이미 몇 가지 이상한 행동을 컴파일하는 것을 보았다. –

답변

13

그러나 java.util.Map 인터페이스에 정의 된 그런 방법은 없습니다! 거기

Map 인터페이스에있어서 Map#remove(Object, Object)이고; 그것은 Java 8에서 추가되었습니다. 따라서 오류가 발생했습니다.

+0

오 와우 ... Java 7 API를 살펴 보았습니다. 고마워, 내가 대답 할 때 대답 해줄거야. – TheBrownMotie

1

Java 일반 유형이 바이트 코드로 변환 될 때 이것은 삭제 유형 프로세스입니다.

Map에서 런타임에 default boolean remove(Object key, Object value) (이 메소드는 Java 8의 새로운 기능)이 MultiMap 클래스 public boolean remove(K key, V value)에서 사용한 메소드와 동일합니다.

는 컴파일러는이를보고, 따라서 에러 보여준다

이름 충돌 :있어서 삭제 (K를 V) 형과 multimap 형 AbstractMap의 제거 (개체, 개체)과 동일한 소거가 있지만 수행 아니 그것을 무시하십시오.

이 참조 : http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html