@starblue, y a-t-il un exemple réel où le type d'octet Java est applicable?
Thorbjørn Ravn Andersen
Si des données sont spécifiées sous forme d'octet, utilisez un Java bytepour plus de clarté, par exemple dans les paramètres. Dans ce cas, le fait que vous ne puissiez pas attribuer de intvaleurs détectera même quelques bogues. Ou utilisez bytepour économiser de l'espace dans les tableaux. Je n'utiliserais pas bytepour une valeur unique qui rentre juste dans un octet.
starblue
Réponses:
172
Les constantes sont évaluées comme des ints, donc 2147483647 + 1débordent et vous donnent un nouvel int, qui est assignable à int, tout en étant 127 + 1également évalué comme intégal à 128, et il n'est pas assignable à byte.
Le problème est le type intdû à la promotion numérique binaire, la valeur 127est un hareng rouge.
starblue du
Je préférerais que les constantes soient évaluées avec une précision infinie et donnent également une erreur sur int i = 2147483647 + 1;
Eduardo
@MByD: Comme vous l'avez dit " while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.", cela signifie-t-il que 50 + 1 seront évalués comme byteet donc assignables byte?
Bhushan
1
@ 10101010 - pas exactement. il sera assignable à byte, mais d'abord (selon la norme) il sera évalué comme int.
MByD
35
Le littéral 127 désigne une valeur de type int. Il en va de même pour le littéral 1. La somme de ces deux est l'entier 128. Le problème, dans le second cas, est que vous l'assignez à une variable de type octet. Cela n'a rien à voir avec la valeur réelle des expressions. Cela a à voir avec Java ne prenant pas en charge les coercitions (*). Vous devez ajouter un transtypage
byte b =(byte)(127+1);
puis il compile.
(*) du moins pas du genre String-to-integer, float-to-Time, ... Java prend en charge les coercitions si elles ne sont, en un sens, pas de perte (Java appelle cela "élargissement").
Et non, le mot «coercition» n'avait pas besoin d'être corrigé. Il a été choisi très délibérément et correctement à cela. De la source la plus proche (Wikipédia): "Dans la plupart des langues, le mot coercition est utilisé pour désigner une conversion implicite , soit pendant la compilation, soit pendant l'exécution." et "En informatique, la conversion de type, le transtypage et la coercition sont différentes manières de changer, implicitement ou explicitement, une entité d'un type de données en un autre.".
Votre exemple de code devrait probablement être byte b = (byte) 127 + 1; qui est «Ajouter 1 à une valeur d'octet maxed out», votre exemple transforme simplement la valeur int de 128 en une valeur d'octet.
NKCSS
6
@NKCSS - Je ne pense pas que vous ayez raison, ceci - (byte)(127 + 1)transtypez 128 (entier) en octet, tandis que cela (byte)127 + 1transforme le 127 en octet, mais encore une fois en int, car il est ajouté à 1 (int) et vous get 128 (int) et l'erreur reste.
MByD
6
Comme preuve pour @MByD:
Le code suivant se compile:
byte c =(byte)(127+1);
Parce que bien que l'expression (127 + 1)soit int et au-delà de la portée hors bytetype, le résultat est converti en byte. Cette expression produit -128.
De plus, si l'expression est une expression constante (§15.28) de type byte, short, char ou int:
Une conversion primitive restrictive peut être utilisée si le type de la variable est byte, short ou char, et que la valeur de l'expression constante est représentable dans le type de la variable.
Sans cette clause, nous ne pourrions pas écrire
byte x =0;char c =0;
Mais devrions-nous être capables de faire cela? Je ne pense pas. Il y a pas mal de magie dans la conversion parmi les primitifs, il faut être très prudent. Je ferais de mon mieux pour écrire
quant à la question devrions-nous être en mesure de ... je ne vois vraiment rien de mal avec byte x = 0mais là encore, je suis un programmeur C.
Grady Player
Je pourrais peut-être voir un argument contre char c = 0, mais pourquoi l'octet x = 0 est-il faux?
Michael Burge
C'est trompeur pour les yeux non avertis, pensant qu'ils attribuent un octet 0 à une variable d'octet. Pas beaucoup de mal dans cet exemple, mais en général, opérer sur byte / short / char peut être très déroutant en raison de conversions implicites. Ils sont beaucoup plus compliqués qu'on ne le pense. Je veux autant de clarté que possible dans mon code, n'introduisez aucune incertitude dans le but d'enregistrer quelques touches.
irréprochable
Une règle similaire s'applique-t-elle lorsque la conversion primitive de rétrécissement est de long en int, par exemple int i = 1 + 0L? Juste demander parce que votre texte cité exclut explicitement ce cas.
byte
type de données est-il si pénible?!byte
est signée au lieu de non signée.byte
pour plus de clarté, par exemple dans les paramètres. Dans ce cas, le fait que vous ne puissiez pas attribuer deint
valeurs détectera même quelques bogues. Ou utilisezbyte
pour économiser de l'espace dans les tableaux. Je n'utiliserais pasbyte
pour une valeur unique qui rentre juste dans un octet.Réponses:
Les constantes sont évaluées comme des ints, donc
2147483647 + 1
débordent et vous donnent un nouvel int, qui est assignable àint
, tout en étant127 + 1
également évalué commeint
égal à128
, et il n'est pas assignable àbyte
.la source
int
dû à la promotion numérique binaire, la valeur127
est un hareng rouge.while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.
", cela signifie-t-il que 50 + 1 seront évalués commebyte
et donc assignablesbyte
?Le littéral 127 désigne une valeur de type int. Il en va de même pour le littéral 1. La somme de ces deux est l'entier 128. Le problème, dans le second cas, est que vous l'assignez à une variable de type octet. Cela n'a rien à voir avec la valeur réelle des expressions. Cela a à voir avec Java ne prenant pas en charge les coercitions (*). Vous devez ajouter un transtypage
puis il compile.
(*) du moins pas du genre String-to-integer, float-to-Time, ... Java prend en charge les coercitions si elles ne sont, en un sens, pas de perte (Java appelle cela "élargissement").
Et non, le mot «coercition» n'avait pas besoin d'être corrigé. Il a été choisi très délibérément et correctement à cela. De la source la plus proche (Wikipédia): "Dans la plupart des langues, le mot coercition est utilisé pour désigner une conversion implicite , soit pendant la compilation, soit pendant l'exécution." et "En informatique, la conversion de type, le transtypage et la coercition sont différentes manières de changer, implicitement ou explicitement, une entité d'un type de données en un autre.".
la source
(byte)(127 + 1)
transtypez 128 (entier) en octet, tandis que cela(byte)127 + 1
transforme le 127 en octet, mais encore une fois en int, car il est ajouté à 1 (int) et vous get 128 (int) et l'erreur reste.Comme preuve pour @MByD:
Le code suivant se compile:
Parce que bien que l'expression
(127 + 1)
soit int et au-delà de la portée horsbyte
type, le résultat est converti enbyte
. Cette expression produit-128
.la source
Conversion d'affectation JLS3 # 5.2
(variable = expression)
De plus, si l'expression est une expression constante (§15.28) de type byte, short, char ou int:
Une conversion primitive restrictive peut être utilisée si le type de la variable est byte, short ou char, et que la valeur de l'expression constante est représentable dans le type de la variable.
Sans cette clause, nous ne pourrions pas écrire
Mais devrions-nous être capables de faire cela? Je ne pense pas. Il y a pas mal de magie dans la conversion parmi les primitifs, il faut être très prudent. Je ferais de mon mieux pour écrire
la source
byte x = 0
mais là encore, je suis un programmeur C.int i=0L
c'est illégal.