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 d'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 le deuxième appel d' 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
En tout cas, même si <T>
est lié à l' Object
, ce qui le rend à la fois setValue
méthodes acceptables candidats pour l'invocation, l'un avec l' 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 mentionnées dans les spécifications sont assez spéciales, lorsque les génériques sont impliqués. Mais je trouve cela un peu confus:
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>
liés à l' Object
à setValue
invocation du temps, en ajoutant des supplémentaires de, sans ambiguïté indirection appelés setValue0
. Cela me fait penser que la liaison de l' T
de Object
c'est vraiment ce qui est la cause de tous les ennuis 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) {
// Quite obviously, this call is not ambiguous
setValue(parameter, value);
}
public void test() {
Parameter<Object> p2 = p2();
Field<Object> f2 = f2();
setValue0(p2, f2);
}
Suis-je un 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 que cela intéresse, 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 en javac