Avant Java 5, il n'y avait aucun autoboxing ou auto-déballage. Cela signifie que si une méthode foo
avait un paramètre de type Integer
, ce qui suit ne compile pas
foo(5); // 5 needs to be autoboxed
De même, si une méthode bar
avait un paramètre de type int
, cela ne compile pas
bar(new Integer(5)); // The Integer needs to be unboxed
Lorsque l'autoboxing et l'auto-unboxing ont été introduits, il était essentiel que le code existant continue à fonctionner exactement de la même manière qu'avant. Par conséquent, lorsque le compilateur décide quelle méthode est appelée, il ne considère d'abord que les méthodes applicables qui ne nécessitent pas d'autoboxing ou d'auto-unboxing. Ce n'est que s'il n'y a pas de telles méthodes que le compilateur considère les méthodes nécessitant un autoboxing et/ou un auto-unboxing.
Depuis getId
retourne un Integer
, la méthode Object
, Object
peut être appelée sans autoboxing dans le cas où le premier argument est également un Integer
. Cependant, la méthode int
, int
ne peut être appelée que par désintoxication automatique du second paramètre. Par conséquent, dans votre deuxième exemple, la surcharge Object
, Object
est sélectionnée lors du premier passage. Dans votre premier exemple, vous essayez de passer un int
et un Integer
. La méthode int
, int
s'applique uniquement en dés-déballant automatiquement le second argument, tandis que la méthode Object
, Object
s'applique uniquement en décochant automatiquement le premier argument. Par conséquent, la surcharge ne peut pas être choisie lors du premier passage, et comme aucune méthode n'est plus spécifique que l'autre (vous aurez besoin de regarder ce dernier bit), le compilateur ne peut pas choisir entre les deux méthodes.
La résolution de surcharge est extrêmement compliquée, et je l'ai simplifiée un peu (il y a aussi des règles impliquant var-args). Cependant, dans la pratique, vous n'avez pas besoin d'apprendre toutes ces règles - si jamais vous devez dire au compilateur quelle méthode vous pouvez appliquer toujours inclure un casting ou explicite des moulages:
assertEquals((Integer) id, friend.getId());
Avez-vous défini le 'id' de 'Friend' être un' int' ou un 'Integer'? – GriffeyDog
L'ID est un entier – user2782067
Pouvez-vous confirmer que le type de retour de getId() est Integer non int? –