31 votes

Pourquoi java encourage-t-il le paramètre long à float / double alors qu’aucune méthode n’accepte long?

Voici un SSCCE qui illustre le comportement décrit (IMHO, bizarre):

 public class Test {

   public static void print(int param) {
       System.out.println("int");
   }

   public static void print(float param) {
       System.out.println("float");
   }

   public static void print(Long param) { //<--Wrapper type
       System.out.println("Long");
   }
   public static void main(String[] args) {
       long param = 100L;
       print(param);  // output == float
   }
} 
 

Pourquoi java fait-il cela?

31voto

Tomasz Nurkiewicz Points 140462

Java Langage de Spécification est assez clair sur ce (l'emphase est mienne):

15.12.2 Au Moment De La Compilation Étape 2: Déterminer La Signature De La Méthode

[...]

  1. La première phase (§15.12.2.2) effectue la résolution de surcharge , sans permettre la boxe ou l'unboxing de conversion [...] Si non applicable méthode est trouvé au cours de cette phase, puis de continuer le traitement pour la deuxième phase. [...]

  2. La deuxième phase (§15.12.2.3) effectue la résolution de surcharge tout en permettant boxing et unboxing [...]

  3. La troisième phase (§15.12.2.4) permet de surcharger être combinée avec une variable arité de méthodes, de boxe, et unboxing.

C'est, dans la première étape seulement print(int) et print(float) , peuvent être appropriées. Les derniers matchs et aucune enquête complémentaire n'est effectué.


La raison de ces règles est expliqué dans JLS ainsi:

Cela garantit que tous les appels qui étaient valables dans le langage de programmation Java avant de Java SE 5.0 ne sont pas considérés comme ambigus comme le résultat de l'introduction de la variable arité de méthodes implicites de la boxe et/ou unboxing.

Imaginez que votre Test classe a été compilé avec Java 1.4 (avant l'autoboxing). Dans ce cas, c'est clair: print(float) doit être choisi (en supposant que nous sommes d'accord pourquoi long de float est considéré comme sûr et peut être implicite...) en print(Long) est totalement incompatible avec long argument.

Plus tard, vous compiler le même code Java 5+. Le compilateur peut:

  • choisissez print(Long) comme plus "évident" dans ce contexte. Ainsi, après la mise à jour de Java 5 votre programme se comporte de la même façon...

  • le rendement d'erreur de compilation que l'appel est ambigu. Ainsi, déjà correcte code n'est plus la compilation sous Java 5 (qui AFAIR n'est jamais le cas)

  • ...ou préserver les vieux de la sémantique et de l'appel à la même méthode que sous Java 1.4

Vous devriez maintenant comprendre pourquoi print(float) - les, parce qu'il aurait été choisie dans le cadre de Java 1.4. Et Java doit être compatible.

12voto

Peter Lawrey Points 229686

La raison pour laquelle il a choisi float sur Long est que la mise en correspondance automatique a été ajoutée plus tard et que, pour des raisons de compatibilité ascendante, il devrait toujours effectuer le même appel.

7voto

Tomasz Nurkiewicz points à la partie de la spécification (15.12.2 en Java SE 7 JLS), mais pourquoi faire? Pour assurer la compatibilité du code source qui cible 1.4 et antérieures doivent continuer à appeler la même méthode surchargée. Par conséquent, les fonctions de 1,5 doivent être ignorés, et seulement si le code ne serait pas autrement compilation doit l'autoboxing être envisagée.

Pourquoi la conversion de long de float peut être implicite - c'est juste une douteuse choix de conception.

4voto

MrSmith42 Points 5159

Voir la documentation

Chapitre 5. Les Conversions et les Promotions

5.1.2. L'Élargissement Des Primitives De Conversion

19 conversions spécifiques sur les types primitifs sont appelés à l'élargissement primitive conversions:

  • byte short, int, long, float ou double
  • short int, long, float ou double
  • char, int, long, float ou double
  • int, long, float ou double
  • long float ou double
  • flotteur à double

Ainsi, la conversion formulaire long de float est ainsi que le règlement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X