2009-10-23 17 views
3

EDIT: Cela n'a pas été un problème avec le code du tout, mais avec un bug dans le plugin Eclipse Groovy (http://jira.codehaus.org/browse/GRECLIPSE-373)Java type ambigu pour la méthode?

Eclipse me donne un message d'erreur bizarre sur les types ambigus dans un programme Java et je ne comprends vraiment pas pourquoi. J'ai une interface qui prend un paramètre générique indiquant quel type de données il retourne.

public interface InterfaceA<T> { 
    T getData(); 
} 

L'une des implémentations de celui-ci ressemble à ceci:

public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> { 
    public Collection<T> getData() { 
     // get the data 
    } 
} 

Il y a aussi un récipient pour un InterfaceA

public class Container<T extends InterfaceA> 
{ 
    private T a; 

    public Container(T a) { 
     this.a = a; 
    } 

    public T getA() { 
     return a; 
    } 
} 

Faire cela provoque l'erreur "getData est ambigu".

Container<Impl<AnotherClass>> c = new Container(new Impl<AnotherClass>()); 
Collection<AnotherClass> coll = c.getA().getData(); 

Je suis perplexe sur celui-ci.

+0

Ne pas voir ce problème dans Eclipse 3.4.2 en utilisant JDK 1.6.0_10 – Nate

+0

Peut-être avez-vous besoin de nous fournir des détails sur 'AnotherClass'. J'ai juste essayé 'java.util.Date' (c'est non-final) à la place de' AnotherClass' et il compile bien dans Eclipse. Juste un mineur, il vous manque 'interface' dans' InterfaceA' et 'getData' devrait être public dans' Impl' –

+0

J'utilise Eclipse 3.5 avec JDK 1.6.0_16, mais j'ai réalisé que je n'ai pas publié de code cassé. J'ai mis à jour le code avec le problème réel. –

Répondre

5

Il semble y avoir un bug provoquant ce plug-in du groovy. http://jira.codehaus.org/browse/GRECLIPSE-373. Ce n'est pas un problème Java du tout. Merci pour l'aide et mes excuses.

+0

Pouvez-vous modifier la question pour l'inclure? – mkb

+0

J'ai mis à jour la question avec cette info en haut. –

+1

Aucune excuse nécessaire, je parie que votre question sera utile à quelqu'un d'autre (comme moi, par exemple;)) – jambriz

0

Votre exemple édité fonctionne bien pour moi (JDK 1.5) à l'exception, que vous devez définir le type générique sur le constructeur. Voici mon code de travail complet:

public interface InterfaceA<T> { 
    T getData(); 
} 

public static class Impl<T extends Date> implements InterfaceA<Collection<T>> { 
    public Collection<T> getData() { 
     return null; 
    } 
} 

public static class Container<T extends InterfaceA> { 
    private T a; 

    public Container(T a) { 
     this.a = a; 
    } 

    public T getA() { 
     return a; 
    } 

} 

public static void main(String[] args) { 
    Container<Impl<Date>> c = new Container<Impl<Date>>(new Impl<Date>()); 
    Collection<Date> coll = c.getA().getData(); 
} 
2

Collection<T> getData() défini dans Impl doit être fait public. Si je fais cela, le code compile proprement pour moi.

+0

Oui, désolé, c'était une erreur de copier/coller. J'ai réalisé que le code que j'ai posté n'était pas erroné, mais j'ai mis à jour le code qui pose problème. –

0

Ce que vous avez ici semble légitime. Peut-être que Eclipse montre une erreur qu'il ne devrait pas autrement. Allez dans Windows> Préférences> Java> Compilateur> Erreurs/Avertissements. Dans la section "Types génériques", assurez-vous qu'Eclipse ne signale aucune erreur pour aucune des opérations répertoriées (sauf si vous le souhaitez également). J'ai tous les miens dans cette section mis à "Avertissement". J'essayerais alors de rafraîchir le projet et de redémarrer Eclipse. Après la publication de la mise à jour, j'ai reçu un avertissement (pas encore d'erreur) sur les lignes d'utilisation, en disant: «Le conteneur est un type brut.» Les références au type générique Container doivent être paramétrées: «. Cela peut être corrigé par:

Container<Impl<Date>> c = new Container<Impl<Date>>(new Impl<Date>()); 

(Dans mon exemple, je suis en utilisant java.util.Date comme à la place de 'AnotherClass').

+0

faute de frappe. J'ai édité la question –

+0

Il ne compile pas proprement pour moi ... ne peut pas @Override une implémentation de méthode d'interface - il devrait être une superclasse à la place. – Nate

+2

@Nate: vous utilisez 1.5. Cuga est sur 1.6. – alphazero

0

[Modifier pour refléter la question à jour]

Cela ne devrait pas même compiler que vous réduisez la visibilité de la méthode du public empaqueter portée:

public class Impl<T extends AnotherClass> implements InterfaceA<Collection<T>> { 
    Collection<T> getData() { 
     // get the data 
    } 
} 

Et ce encore compile pour moi (Eclispe 3.4, OS X, 1.5), donc je ne sais pas exactement quel est le problème:

package temp.tests;

import java.util.Collection; 

public interface InterfaceA <T> { 

    T getData(); 

    public static final class AnotherClass {} 

    public static final class Impl<T extends AnotherClass> 
      implements InterfaceA<Collection<T>> 
    { 
     public Collection<T> getData() { 
      return null; 
     } 
    } 

    public static class Container<T extends InterfaceA> 
    { 
     private T a; 
     public Container(T a) { this.a = a; } 
     public T getA() { return a; } 
    } 

    public static final class Test { 
     public static void main (String[] args) { 
      Container<Impl<AnotherClass>> c = new Container(new Impl<AnotherClass>()); 
      Collection<AnotherClass> coll = c.getA().getData(); 
     } 
    } 
} 
+0

Merci de votre attention. J'ai posté une réponse concernant le plugin groovy/eclipse. Il s'avère que c'était le coupable. –

+0

NP! Vous voudrez peut-être ajouter cela comme mise à jour à votre question. – alphazero

0

Comme d'autres affiches l'ont dit, je ne vois pas ce problème sur Eclipse 3.5.0 fonctionnant sur JDK 1.6.0.14 (lors de la fixation de la visibilité réduite de la méthode getData()).

Je suggère de faire une construction propre (Projet/Clean in Eclipse). En outre, la version Eclipse et Java que vous utilisez peut vous aider.

- Flaviu Cipcigan

+0

J'ai mis à jour le code pour illustrer correctement le problème. Il éclate toujours en éclipse, mais semble fonctionner si je compile juste avec javac. –