2010-08-11 7 views
2

je reçois le message d'erreur suivant (réduite à la partie importante) quand je compiler mes cours:Java erreur de compilation avec des interfaces

reference to keySet is ambiguous, both method keySet() in 
java.util.SortedMap<E,capture#614 of ?> and method keySet() in 
test.ImmutableMap<E,capture#614 of ?> match 
    return map.keySet().iterator(); 
      ^

map est de type ImmutableSortedMap<E, ?> et la définition des classes immuables regards comme:

public interface ImmutableMap<K, V> 
    extends Map<K, V> { 
    @Override 
    public ImmutableSet<K> keySet(); 
    ... 
} 
public interface ImmutableSortedMap<K, V> 
    extends ImmutableMap<K, V>, SortedMap<K, V> { 
    ... 
} 
public interface ImmutableSet<E> 
    extends Set<E> { 
    ... 
} 

L'erreur apparaît lorsque je compile en utilisant un script ANT ou manuellement, mais pas en éclipse. Je l'ai essayé avec sun 1.6.0 et icedtea6 1.8.1.

Y a-t-il quelque chose d'évident qui me manque ou existe-t-il une option qui peut être définie quelque part dans eclipse pour permettre la compilation? Le truc c'est que, pour l'instant, je peux lancer les tests en eclipse, mais je ne peux pas compiler le projet en dehors d'eclipse.


EDIT: la réponse

Il semble que certaines versions du compilateur ont des problèmes avec l'héritage multiple comme ça. La solution consiste à surcharger la méthode une fois de plus dans la sous-classe héritant d'autres interfaces qui ont une super-interface commune et qui se substituent à la méthode.

public interface ImmutableSortedMap<K, V> 
    extends ImmutableMap<K, V>, SortedMap<K, V> { 
    // adding this method solves the problem 
    @Override 
    public ImmutableSet<K> keySet(); 
} 

Par ailleurs, c'est le problème de diamon.

Répondre

0

Les deux interfaces ImmutableMap et SortedMap ont une méthode nommée "keySet()" pour que le compilateur ne puisse pas savoir lequel appeler. Changer le nom de la méthode dans votre interface;)

+0

Si les méthodes correspondent, alors ce n'est pas un problème. –

+0

Au lieu de changer le nom, la redéclaration de la méthode dans la sous-classe a résolu le problème. – Kru

1

Il me semble, ImmutableMap#keySet a le mauvais type de retour. Il devrait être Set<K> ou ImmutableSet<K>. Si vous souhaitez renvoyer un jeu de paires, remplacez Map#entrySet à la place.

Il n'y a rien de mal si l'interface A étend les interfaces B et C et que B et C ont une méthode avec la même signature (doIt(String param1, int param2)). Mais les types de retour B#doIt et C#doIt devraient être compatibles. Si B#doIt renvoie String et C#doIt renvoie int, nous ne pouvons pas combiner ces deux méthodes dans une classe.

Oh, et je ne sais pas pourquoi il compile sous Eclipse.

+0

J'ai eu la même erreur avec entrySet et j'ai mal saisi le type générique de la méthode. (J'ai corrigé la question) – Kru

+0

@Chris Puis il n'y a rien de mal avec l'échantillon que vous avez fourni (sauf que vous pourriez utiliser des enveloppes immuables standards de jdk). Pouvez-vous montrer comment keySet est implémenté? (sa déclaration là) –

+0

J'ai édité la question et il semble que c'est un problème avec le compilateur qui doit être explicitement dit la signature de la méthode dans ImmutableSortedMap. Je n'utilise pas les wrappers car le coût de création d'une nouvelle structure immuable qui est la structure d'origine avec seulement quelques éléments modifiés nécessite une copie de la structure entière. L'implémentation n'est pas révélatrice ici et utilise beaucoup d'autres fonctions ... c'est trop gros pour la mettre ici. – Kru