Référence est ambiguë avec les génériques

Je suis tout à fait avoir un cas délicat ici avec les médicaments génériques et de la surcharge de méthode. Découvrez cette classe exemple:

public class Test {
    public <T> void setValue(Parameter<T> parameter, T value) {
    }

    public <T> void setValue(Parameter<T> parameter, Field<T> value) {
    }

    public void test() {
        //This works perfectly. <T> is bound to String
        //ambiguity between setValue(.., String) and setValue(.., Field)
        //is impossible as String and Field are incompatible
        Parameter<String> p1 = getP1();
        Field<String> f1 = getF1();
        setValue(p1, f1);

        //This causes issues. <T> is bound to Object
        //ambiguity between setValue(.., Object) and setValue(.., Field)
        //is possible as Object and Field are compatible
        Parameter<Object> p2 = getP2();
        Field<Object> f2 = getF2();
        setValue(p2, f2);
    }

    private Parameter<String> getP1() {...}
    private Parameter<Object> getP2() {...}

    private Field<String> getF1() {...}
    private Field<Object> getF2() {...}
}

L'exemple ci-dessus compile parfaitement dans Eclipse (Java 1.6), mais pas avec la Fourmi commande javac (ou avec le JDK de commande de javac), où je reçois ce type de message d'erreur sur la deuxième invocation de setValue:

référence à setValue est ambigu,
les deux méthode
setValue(org.jooq.Paramètre,T)
dans l'Essai et la méthode
setValue(org.jooq.Paramètre,org.jooq.Champ)
en Test match

Selon le cahier des charges et à ma compréhension de la façon dont le compilateur Java fonctionne, le plus spécifique de la méthode doit toujours être choisi: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#20448

Dans tous les cas, même si <T> est lié à Object, ce qui le rend à la fois setValue méthodes acceptables candidats pour l'invocation, l'un avec le Field paramètre semble toujours être plus précis. Et cela fonctionne dans Eclipse, mais pas avec le JDK du compilateur.

Mise à JOUR:

Comme cela, il serait de travailler à la fois dans Eclipse et avec le JDK compilateur (avec rawtypes mises en garde, bien sûr). Je comprends que les règles spécifiées dans les spécifications sont assez spéciales, lorsque les génériques sont impliqués. Mais je trouve cela plutôt déroutant:

    public <T> void setValue(Parameter<T> parameter, Object value) {
    }

    //Here, it's easy to see that this method is more specific
    public <T> void setValue(Parameter<T> parameter, Field value) {
    }

Mise à JOUR 2:

Même avec les génériques, je peux créer cette solution de contournement, où j'ai éviter le type <T> être lié à des Object à setValue invocation du temps, en ajoutant des supplémentaires de, sans ambiguïté indirection appelé setValue0. Cela me fait penser que la liaison de T à Object est vraiment ce qui est à l'origine de tous les problèmes ici:

    public <T> void setValue(Parameter<T> parameter, T value) {
    }

    public <T> void setValue(Parameter<T> parameter, Field<T> value) {
    }

    public <T> void setValue0(Parameter<T> parameter, Field<T> value) {
        //This call wasn't ambiguous in Java 7
        //It is now ambiguous in Java 8!
        setValue(parameter, value);
    }

    public void test() {
        Parameter<Object> p2 = p2();
        Field<Object> f2 = f2();
        setValue0(p2, f2);
    }

Suis-je malentendu quelque chose ici? Est-il connu du compilateur bug lié à cela? Ou est-il une solution/compilateur paramètre pour m'aider?

Suivi:

Pour ceux qui sont intéressés, j'ai déposé un rapport de bug à la fois à Oracle et Eclipse. Oracle a accepté le bug, jusqu'à présent, Eclipse a analysé et l'a rejeté! Il semble que si mon intuition est bonne et c'est un bug dans javac

  • je pense que, ant est pointant vers les différentes compilateur, ce qui n'est pas une release candidate.
  • ant utilise le JDK est javac compilateur. C'est Eclipse qui peut avoir sa propre...
InformationsquelleAutor Lukas Eder | 2011-03-19