Bonsoir
Pourquoi l'entier 5 peut être implicitement converti en short dans ce cas
mais pas dans celui là ?Code:
1
2 short i = 5;
Merci d'avanceCode:
1
2
3
4
5 void afficher(short i) { ... } public static void main(String[] Args) { afficher(5); }
Version imprimable
Bonsoir
Pourquoi l'entier 5 peut être implicitement converti en short dans ce cas
mais pas dans celui là ?Code:
1
2 short i = 5;
Merci d'avanceCode:
1
2
3
4
5 void afficher(short i) { ... } public static void main(String[] Args) { afficher(5); }
Ce n'est pas une question de conversion, en fait.
5 est un littéral numérique. En tant que tel, il peut être considéré comme un byte, un short, un int, un long, un char, un float ou un double. Il n'est même pas converti, il est n'importe lequel de ces types.
Toutefois, le fait qu'il puisse être n'importe lequel de tous ces types crée une ambiguïté dans le cas d'un appel de méthode.
Supposons que tu aies aussi une méthode afficher(int i). Dans ce cas, en appelant afficher(5), comment le compilateur doit-il choisir entre afficher(int i) et afficher(short i) ?
Eh bien, il le fait en considérant que dans un appel de méthode, les littéraux numériques de cette forme ne peuvent être que des int. Donc pour un short, byte, ou char, il faut expliciter leur type. Avec un cast, ou alors d'abord déclarer une variable de ce type, lui assigner la valeur, et appeler la méthode avec cette variable.
Dans une instruction d'assignation, le problème ne se pose pas : on sait quel doit être le type de 5 en regardant le type de la variable assignée.
Ce qui peut se redire autrement :
5 est une expression numérique littérale, de type int dans les conditions de typage ambiguës, et de type byte, short, int, long, char, float ou double dans les conditions de typage déterministes.
Un truc qui peut aider à comprendre : il se passe quoi en faisant :
?Code:
1
2 byte b1 = 5; byte b2 = 256;
Merci pour votre réponse thelvin,
j'ai lus dans un bouquin que :
byte b = 27; est traduite par le compilateur en byte b = (byte)27;
j'ai compris que ça passe quand il n'y a pas de pertes d'infos, (vu que 27 peut tenir dans un byte).
Ceci dit, si j'avais mis:
cela ne marchera pas, même si 27 peut tenir sans problème dans un byte, comme si le compilateur ne cherché pas a connaitre la valeur de iCode:
1
2
3 int i = 27; byte b = i;
j'avais pensé que quand j'appelais afficher(5); il y' avais peut être une variable int qui se créé automatiquement et qui contenait la valeur 5, et dont on reviens a passé un variable int a un byte, donc le cast est nécessaire.
non?
Justement, le compilateur ne cherche pas à le savoir, c'est pas du tout son rôle. Là, i vient de l'instruction du dessus, qui est une expression constante, donc le compilateur pourrait inférer sa valeur et voir que ça passe dans un byte. Mais par cohérence avec le cas général, il ne le fait pas. Dans le cas général, la valeur de i est inconnue du compilateur.
Nieh ? Pas tout compris.
j'ai commis une erreur de frape donc à la place de dont;
c'est juste ce que j'avais compris, bon voilà:
le compilateur créera en interne une variable disons parametre1 de type int qui contient 5; ça serai quelque chose du genre:Code:
1
2 afficher(5);
et on a la méthode qui accepte un byte, et donc impossible de convertir depuis : parametre1 à i (une variable de type int en byte) ,ça serai plutôt pareil à :Code:
1
2
3 parametre1 = 5; afficher(parametre1);
je sais pas si c'est clair ce que je dit ..Code:
1
2
3 int i = 27; byte b = i;
Ma foi, c'est comme ça que le langage est défini.
Se rappeler toutefois que les expressions constantes de type int, peuvent être assignées à des places d'autres types, du moment que la valeur de l'expression constante est dans l'intervalle du type de la place.
Et qu'un paramètre d'appel de méthode n'est pas considéré comme une place.
Bref, qu'on peut faire :
mais pas :Code:
1
2
3
4 byte b = 5; byte[] array1 = new byte[1]; array1[0] = 5; byte[] array2 = {5, 6, 7};
Code:
1
2
3
4
5void traiter(byte b) { } void do() { traiter(5); }
j'ai pas compris :oops:Code:
1
2 Et qu'un paramètre d'appel de méthode n'est pas considéré comme une place.
Un truc auquel on peut assigner une valeur.
(Des fois ça me rend pas service d'avoir fait de la définition formelle de langages, pas moyen de décrire les notions simples.)
quelle que que soit la ligne, 5 est un int (pas un short, pas un byte, pas un long, un int). Tout les nombre numérique sans virgule sont considéré comme des int par le language (sauf indicateur explicite comme L). Ensuite donc, tu te retrouve ainsi avec deux choses:
Dans le premier cas, le compilateur sais qu'il dois faire une conversion implicite vers short, et tant que la valeur immédiate est connue du compilateur, si la valeur est dans les limites admines il peux le faire.Code:
1
2 int i = <un entier>; afficher(<un entier>);
Dans le deuxième cas, ce sont d'autres règles qui s'appliquent, celles du language concernant le polymorphisme, règles strictes permettant de trouver la bonne méthode. Et dans ces règles, rien n'est prévu pour un casting implicite amenant une perte de précision.
Merci pour votre réponses, c'est plus clair