Il dépend de comment vous voulez appeler ces méthodes. Si vous souhaitez appeler ces méthodes à d'autres le code source de Java, il est considéré comme invalide pour des raisons illustré dans Edwin réponse. C'est une limitation du Langage Java.
Cependant, pas toutes les classes doivent être généré à partir du code source Java (compte de toutes les langues qui utilisent la JVM que leur exécution: JRuby, Jython, etc...). Au niveau du bytecode, la JVM peut lever l'ambiguïté entre les deux méthodes, car le bytecode instructions de spécifier le type de retour qu'ils attendent. Pour exemple, voici une classe écrite en Jasmin que l'on peut appeler l'une de ces méthodes:
.class public CallAmbiguousMethod
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 3
.limit locals 1
; Call the method that returns String
aconst_null
invokestatic TestWillThatCompile/f(Ljava/util/List;)Ljava/lang/String;
; Call the method that returns Integer
aconst_null
invokestatic TestWillThatCompile/f(Ljava/util/List;)Ljava/lang/Integer;
return
.end method
J'ai compiler un fichier de classe à l'aide de la commande suivante:
java-jar jasmin.jar CallAmbiguousMethod.j
Et d'appeler à l'aide:
java CallAmbiguousMethod
Voici, la sortie est:
> java CallAmbiguousMethod
les chaînes
les numéros de
Mise à jour
Simon posté un exemple de programme qui appelle ces méthodes:
import java.util.Arrays;
import java.util.List;
class RealyCompilesAndRunsFine {
public static String f(List<String> list) {
return list.get(0);
}
public static Integer f(List<Integer> list) {
return list.get(0);
}
public static void main(String[] args) {
final String string = f(Arrays.asList("asdf"));
final Integer integer = f(Arrays.asList(123));
System.out.println(string);
System.out.println(integer);
}
}
Voici le bytecode Java généré:
>javap -c RealyCompilesAndRunsFine
Compilé à partir de "RealyCompilesAndRunsFine.java"
classe RealyCompilesAndRunsFine s'étend java.lang.Objet{
RealyCompilesAndRunsFine();
Code:
0: aload_0
1: invokespecial #1; //Méthode java/lang/Object."":()V
4: retour
public static java.lang.String f(java.util.Liste);
Code:
0: aload_0
1: iconst_0
2: invokeinterface #2, 2; //InterfaceMethod java/util/Liste.obtenir:(I)Ljava/lang/Object;
7: checkcast #3; //la classe java/lang/String
10: areturn
public static java.lang.Entier f(java.util.Liste);
Code:
0: aload_0
1: iconst_0
2: invokeinterface #2, 2; //InterfaceMethod java/util/Liste.obtenir:(I)Ljava/lang/Object;
7: checkcast #4; //la classe java/lang/Entier
10: areturn
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: anewarray #3; //la classe java/lang/String
4: dup
5: iconst_0
6: pma #5; //la Chaîne asdf
8: aastore
9: invokestatic #6; //Méthode java/util/Tableaux.asList:([Ljava/lang/Object;)Ljava/util/Liste;
12: invokestatic #7; //la Méthode f:(Ljava/util/Liste;)Ljava/lang/String;
15: astore_1
16: iconst_1
17: anewarray #4; //la classe java/lang/Entier
20: dup
21: iconst_0
22: bipush 123
24: invokestatic #8; //Méthode java/lang/Entier.valueOf:(I)Ljava/lang/Integer;
27: aastore
28: invokestatic #6; //Méthode java/util/Tableaux.asList:([Ljava/lang/Object;)Ljava/util/Liste;
31: invokestatic #9; //la Méthode f:(Ljava/util/Liste;)Ljava/lang/Integer;
34: astore_2
35: getstatic #10; //le Champ java/lang/Système.:Ljava/io/PrintStream;
38: aload_1
39: invokevirtual #11; //Méthode java/io/PrintStream.println:(Ljava/lang/String;)V
42: getstatic #10; //le Champ java/lang/Système.:Ljava/io/PrintStream;
45: aload_2
46: invokevirtual #12; //Méthode java/io/PrintStream.println:(Ljava/lang/Object;)V
49: le retour
Il s'avère que le Soleil compilateur génère du bytecode nécessaire pour lever l'ambiguïté sur les méthodes (voir les instructions 12 et 31 dans la dernière méthode).
Mise à jour #2
La Java Language Specification suggère que cela peut, en fait, être valide, le code source Java. Page 449 (§15.12 Invocation de Méthode Expressions), nous voyons ceci:
Il est possible qu'aucune méthode la plus spécifique, parce qu'il y a deux ou
plusieurs méthodes qui sont spécifiques au maximum. Dans ce cas:
- Si tous le maximum de méthodes spécifiques ont override-équivalent (§8.4.2) les signatures,
alors:
- Si vraiment l'un de la au maximum des méthodes spécifiques n'est pas déclarée abstraite,
il est le plus spécifique de la méthode.
- Sinon, si tous le maximum de méthodes spécifiques sont déclarées abstraites,
et les signatures de tous le maximum de méthodes spécifiques ont la même
l'effacement (§4.6), puis le plus spécifique de la méthode est choisie arbitrairement parmi
le sous-ensemble de la au maximum les méthodes spécifiques qui ont les plus spécifiques
le type de retour. Cependant, la plupart de la méthode spécifique est considéré comme jeter un
vérifié exception si et seulement si cette exception ou son effacement est déclaré dans
les lancers de clauses de chacun le maximum de méthodes spécifiques.
- Sinon, nous pouvons dire que l'invocation de la méthode est ambigu, et une compile-time
erreur se produit.
Sauf erreur de ma part, ce comportement ne devrait s'appliquer qu'à des méthodes déclarées comme abstraite, mais...
Mise à jour #3
Grâce à ILMTitan commentaire:
@Adam Paynter: Votre texte en gras ne
pas grave, car il n'est qu'un cas
lorsque deux méthodes sont
remplacer l'équivalent, qui a montré Dan
n'était pas le cas. Ainsi, l'
facteur déterminant doit être si la JLS
prend des types génériques en compte lors de la
la détermination de la plupart des méthodes spécifiques. –
ILMTitan