У меня есть интерфейс в Java 6, который правильно компилируется:
public interface IMultiMap<K, V> extends Map<K, Set<V>> {
public int valueSize();
public boolean put(K key, V value);
public void clear(Object key);
public boolean isEmpty(Object key);
}
Но в Java 7 этот интерфейс не компилируется. Я получаю ошибку компиляции на boolean put(K, V)
, что она имеет такое же стирание, как V put(K, V)
. Полная ошибка компилятора:
error: name clash: put(K#1,V#1) in IMultiMap and put(K#2,V#2) in Map have the same erasure, yet neither overrides the other
public boolean put(K key, V value);
where K#1,V#1,K#2,V#2 are type-variables:
K#1 extends Object declared in interface IMultiMap
V#1 extends Object declared in interface IMultiMap
K#2 extends Object declared in interface Map
V#2 extends Object declared in interface Map
Для записи добавление какого-либо переопределения не работает. Я попытался явно переопределить Map.put
, но ошибка все же возникает. Изменение типа возврата моего put
является спорным, поскольку эта ошибка блокирует возможную ошибку из когда-либо достигнутой, и если эта ошибка была исправлена, тогда оба метода не имели бы одинакового имени/параметра. >
Я думаю, что я мог бы попробовать некоторое размышление над Java 6 и посмотреть, какие фактические типы параметров заканчиваются в скомпилированном байт-коде Java. Понятно, что оба метода Java 7 стираются до put(Object, Object)
. Я опубликую результаты отражения здесь, когда я это сделаю.
Тем временем мое временное обходное решение будет просто переименовать put
в putSingle
, но верно ли это новое поведение? Изменилась ли какая-то часть спецификаций дженериков для Java 7, что делает неправильное поведение старого Java 6? Или это ошибка в компиляторе Java 7?
Спасибо заранее.
EDIT: Я запустил код отражения. Посмотрите мой ответ ниже.