2014-05-21 14 views
8

Để giải trí, tôi đang cố triển khai bộ sưu tập "MultiMap", giống như những gì đã tồn tại trong thư viện Apache Commons. Tôi nhận được một lỗi thú vị với phương pháp "remove (K key, V value)" của tôi. Trình biên dịch nói rằng có một xung đột tên - rằng nó có cùng xóa như "remove (Object, Object) của kiểu Map". Nhưng không có phương thức nào được định nghĩa trong giao diện java.util.Map! Chỉ có một phương thức "remove (Object)" - với một tham số, trái với hai phiên bản tham số của tôi. Điều thú vị hơn nữa là nếu bạn tự loại bỏ thông tin kiểu bằng cách thay thế "remove (K key, V value)" bằng "remove (Object key, Object value)", nó sẽ biên dịch tốt. Bất cứ ai có thể giải thích hiện tượng này?Lỗi xung đột tên Java, mặc dù có chữ ký phương thức khác nhau

Tôi đang chạy Java 8, trong trường hợp quan trọng.

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

Tôi không gặp lỗi ở đó. I * am * nhận được một lỗi với lệnh gọi 'put (key, new ArrayList <>())'. (Edit: Tôi đã thử điều này với Java 7.) – arshajii

+0

Thú vị. Có lẽ phiên bản quan trọng? Tôi đang chạy Java 8. – TheBrownMotie

+0

@TheBrownMotie Tôi nghĩ rằng nó quan trọng. Tôi đã nhìn thấy đã có một vài biên dịch hành vi lạ trên SO. –

Trả lời

13

Nhưng không có phương pháp như được định nghĩa trong giao diện java.util.Map!

một phương pháp Map#remove(Object, Object) trong giao diện Map; nó đã được thêm vào trong Java 8. Do đó lỗi.

+0

Ồ wow ... Tôi đã xem xét API Java 7. Cảm ơn, tôi sẽ chấp nhận câu trả lời của bạn khi nó cho phép tôi. – TheBrownMotie

1

Điều này là do loại tẩy xóa quy trình khi loại chung Java được dịch sang bytecode.

Khi chạy default boolean remove(Object key, Object value) (phương pháp này là mới trong Java 8) trong Bản đồ giống với phương pháp của bạn ở lớp MultiMap public boolean remove(K key, V value).

Trình biên dịch xem đây, và do đó hiển thị lỗi:

Tên đụng độ: Phương thức remove (K, V) loại Multimap có tẩy xoá giống như remove (Object, Object) của loại AbstractMap nhưng không không phải ghi đè lên.

Xem nội dung này: http://docs.oracle.com/javase/tutorial/java/generics/genTypes.html

Các vấn đề liên quan